Getting rid of index.php in codeigniter with Vhost - .htaccess

I've tried every possible htaccess snippet I could find about this but none will work. My codeigniter projects is found on ci.mydomain.com and I've configured the virtualhost this way
<VirtualHost *:80>
ServerName ci.mydomain.com
ServerAlias ci.mydomain.com
ServerAdmin x#gmail.com
DocumentRoot /var/www/codeigniter
</VirtualHost>
I've also set
$config['index_page'] = '';
I just get 404. What's wrong?
I'm using the latest version 2.1.3
Update
<VirtualHost *:80>
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [PT]
ServerName ci.domain.com
ServerAlias ci.domain.com
ServerAdmin d#d.com
DocumentRoot /var/www/codeigniter
</VirtualHost>
I tried this and it worked for me. Although I would rather use a .htaccess file.
Edit: Guys, the reason I mentioned that I use virtual host is that i suspect that is what causes the problem. But maybe I'm wrong.

The actual workhorse for this is a module named mod_rewrite, it allows you to set up rewrite rules to redirect urls to index.php for processing.
See this article for some more in depth details on how to go about this
Update:
It looks like the rewrite conditions you're using are sort of following the old rules.
The two things I think you're missing (one of which isn't relevant, but helpfull) are:
RewriteBase - I have found specifying a rewrite base goes a long way to helping your rules work better. Technically I think it should work without but I've encountered nothing but problems without it.
RewriteCond Statements for Excluding actual files - Right now your conditions will mask a lot of real files, which probably isn't what you want.
So how do we fix this?
RewriteBase /
This will set the root of your rewrite engine to start after the .com/ this simplifies things because you wont need to deal with the leading /.
As a result you'll need to change your main rewrite rule to this:
RewriteRule ^(.*)$ index.php/$1 [L]
This will redirect .com/anything/you/type to .com/index.php/anything/you/type and the php script can pick that up automatically to pass to the router.
This relys on the condition however because otherwise you'd end up in a loop, so above this line you need these conditions to prevent actual files/folders from being hidden:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
With this !-f means "Not -f" where -f means "Is A File", the same for -d meaning "Is a Directory" so basically you're saying match this rule only if the %{REQUEST_FILENAME} is not a file and is not a directory.
Then any url that points to an actual file will resolve just fine! (Including index.php).
So with the following lines in your .htaccess you should get proper rewriting:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
You should be good to go provided you have mod_rewrite enabled in your apache configuration.
If you're using Apache2 on Ubuntu, the command(s) to enable this is trivial:
a2enmod rewrite
service apache2 reload
It's important the module is actually enabled of all your Rewrite* rules in your apache will not execute.
If that still isn't working you need to go check the apache main configuration to see if there's a subset of commands allowed in the .htaccess files, usually an install is set to All so that anything can be specified there, but often it's locked down to prevent security overlap between customers. You mentioned you're using a VPS so you probably wont have to do this step, but I thought I would mention it for the sake of others.
The option you'd be looking for looks like this:
AllowOverride All
There is one last thing that's mainly a saftey net:
Apache offers a way to gaurd clauses against modules existing
<IfModule mod_rewrite.c>
~~ Put Rewrite* Rules here ~~
</IfModule>
Update 2
Ok I just noticed the Virtual host. I think the problem is you're putting the Rewrite conditions in your <VirtualHost > block, and they need to exist in the <Directory> block for the folder your files are in.
You can do this by removing all Rewrite* rules from your conf and either adding this to your .conf file:
<Directory /var/www/codeigniter>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</Directory>
Or adding a .htaccess file in /var/www/codeigniter with this inside of it:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
These rules apply to the directory, not the VHost declaration, and the .htaccess is a shortcut to the <Directory> block basically.
Useful Links:
Apache mod_rewrite documentation

Related

htaccess: Using silex/symfony and web-directory redirect

I'd like to use silex with a "web"-directory for public files.
The structure will look like:
-project
--vendor
----silex
----...
--web
----index.php
--.htaccess
So I'd like to have a .htaccess script that does this tasks:
If I request a file ./myInstallationPath/file.php it should check if the file exist inside ./myInstallationPath/web/ and if so, redirect to it internal
. Otherwise it should internal redirect to ./myInstallationPath/web/index.php
If I request ./myInstallationPath/web/ it should remove the "web/" from the URL so that the user will not see the "web"-directory. Then the point above should be used.
Because the path of the project can be root, but also a sub-folder, the installation path could determinded the following way:
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=INSTALLATION_ROUTE:%1]
This is my existing code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{ENV:INSTALLATION_ROUTE}web/$1 !-f [NC]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:INSTALLATION_ROUTE}web/$1 !-d [NC]
RewriteRule (.*) %{ENV:INSTALLATION_ROUTE}web/index.php [L]
It'll check if the file does not exist inside web/ and if so, it will redirect to index.php How must the other rules look like, to meet the requirements?
I recommend you to use Apache Virtual Hosts. My project structure looks like yours. I use this in http.conf for creating the virtual host:
<VirtualHost localhost:80>
ServerAdmin localhost
DocumentRoot "c:/apachefolder/htdocs/"
ServerName localhost
ServerAlias localhost
</VirtualHost>
<VirtualHost localhost:80>
DocumentRoot "C:/apachefolder/htdocs/mysilexproject/web"
ServerName myproject.dev
ServerAlias myproject.dev
</VirtualHost>
I added first the localhost one to still being able to access other sites like before using VirtualHosts.
Once you have created the VHost, you will have to set the dummy domain you have used for you project in you system host file.
In case of Windows C:\Windows\System32\drivers\etc
/etc/hosts for most linux distros
After this I put in the web directory of my project my .htaccess file that looks like this:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
Finally restart your apache to get the config changes applied. Now you will be able to access your site using http://myproject.dev

url redirection in the default .htaccess file

I would like to map "http://www.example.com/abc" to "http://www.example.com/test/abc" for having the shortest route possible. I am using pyroCMS for my users and content.
the default pyrocms file:
# Multiple Environment config
# Set this to development, staging or production
# SetEnv PYRO_ENV production
<IfModule mod_rewrite.c>
# Make sure directory listing is disabled
Options +FollowSymLinks -Indexes
# disable the Apache MultiViews directive if it is enabled on the server. It plays havoc with URL rewriting
Options -MultiViews
RewriteEngine on
# Keep people out of codeigniter directory and Git/Mercurial data
RedirectMatch 403 ^/.*/(vendor|composer\.json|composer\.lock|system/cms/cache|system/codeigniter|system/cms/config|system/cms/logs|\.git|\.hg).*$
# Send request via index.php (again, not if its a real file or folder)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
<IfModule mod_php5.c>
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_php5.c>
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
</IfModule>
I would like to add this rule to the file:
RewriteRule ^([a-z0-9_]+)$ test/$1
To rewrite "BASE_URL/abc" to "BASE_URL/test/abc"
However,
i tried many positions as to where to put this RewriteRule, my website keeps giving a "Page Missing".
Is my RewriteRule ok? And where do i insert it?
PyroCMS has built-in modular routing ability. see here:
http://docs.pyrocms.com/2.2/manual/developers/basics/modular-routing
If your "http://www.example.com/abc" refers to a custom module,then, you can add a file named "routes.php" in a in config folder of your module.
the folder construction should like this :
addones/shared_addons/modules/your-module/config/routes.php
OR even you can edit the core route config file located at system/cms/config/routes.php and add this line or whatever your routing rules are:
$route['abd'] = 'test/abd';
OR more even, at your control pannel there is a redirect module that you can add redirections.
It all depends on what your rule is supposed to do and how it is supposed to interact (or not interact) with the rest of your site. And considering your entire htaccess file is mostly commented out code (which I removed to make it halfway readable), you just want to place it under RewriteEngine On.
However, since it blindly routes everything into test you need to add a few conditions and make it something lilke:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/test%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/test%{REQUEST_URI} -d
RewriteRule ^([a-z0-9_]+)$ test/$1 [L]

symfony2 on shared hosting

I've been working on this for quite a while to no avail.. I've got symfony installed on a shared web-host where I have zero access to change the DocumentRoot to the web/ folder so that is not an option to me...
I've written my htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^$ web/app.php [QSA]
RewriteRule ^(.*)$ web/app.php/$1 [QSA, L]
I have also tried this with RewriteBase web/ and RewriteBase /web/ to no avail.
With this, symfony is working.. I can login, I can do all of that... Only problem is, none of the assets are displaying... Chrome Developer Tools, is telling me it's finding a 404 which is right because it's not reading the /web/ folder as the DocumentRoot..
So, how to fix this issue without re-writing files, or anything.. There's got to be a way to do this with .htaccess only...
One way would be setting assets_base_urls in app/config.yml e.g
framework:
#..
templating:
engines: ['twig']
assets_base_urls: http://your.site.com/web/
Or, you can put a .htaccess file in your DocumentRoot folder and rewrite everything that comes in there to your /web folder accordingly:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /web/$1 [QSA,L]
</IfModule>
With that you get clean URL's (omitting "web" or "app.php") and there is no need to use the assets_base_urls stuff in your config.

Need to use httpd.conf instead of .htaccess for rewrite

I am working on a host that blocks my .htaccess file from being used so I can not change my permalinks using it. I need to figure out what code to use and where to put it in my httpd.conf file to get the same effect.
The code in the .htaccess file is below:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wordpress/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
</IfModule>
You'll need to wrap that code in a <Directory> directive. Where it goes will depend on what else you've got in your http.conf file. See the Apache docs for more info.
However, as blockhead says; if your host won't let you use .htaccess files, you've got virtually no chance of being allowed near the httpd.conf file.
For example, if you'd like to block access to GoogleBot throughout your entire server (which may be comprised of hundreds of virtual hosts), you can add this to your httpd.conf file:
#setup the root dir
<Directory />
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} Googlebot
RewriteRule .* - [F,L]
</Directory>
This will send a HTTP 403 Forbidden to anyone who comes in with Googlebot in their user agent string. And this rewrite condition will be applied to ALL virtual hosts, by virtue of applying this to the "/" folder.

How can I write an .htaccess that will rewrite differently based on the request url?

I would like to have one .htaccess file that can rewrite correctly on both my localhost development environment and on my hosted production site. Right now I have to keep two separate file copies for every site I work on. I would like to be able to synchronize the two sites without blowing away either one of their .htaccess files.
Below is the .htaccess file that I'm using with a little pseudo code in the comments to demonstrate what I want to do.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
## IF the url looks like its from localhost then use this rule
## The incoming url might look like: http://localhost/mysite/about
RewriteRule ^(.*)$ /mysite/index.php/$1 [L]
## Else do this rewrite
## The incoming url might look like: http://www.mysite.com/about
RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
Here is my server configurations:
Development: xampp on windows
Production: Dreamhost
I'm a bit rusty on this, but I think:
RewriteCond %{HTTP_HOST} ^www.domain.com$ [NC]
#Do your live stuff here
RewriteCond %{HTTP_HOST} ^localhost$ [NC]
#Do your local stuff here
Use RewriteCond to check %{HTTP_HOST}. eg:
RewriteCond %{REMOTE_HOST} ^localhost$
I would just use a separate virtual host for your development environment with the same settings as your production server has.
Just add another <VirtualHost> container to your httpd.conf or httpd-vhosts.conf configuration file and adjust the settings:
<VirtualHost *:80>
ServerName example.com.local
DocumentRoot /absolute/filesystem/path/to/your/localhost/mysite
</VirtualHost>

Resources