Taken by the frustration of a ridicolous amount of time wasted in understanding why this thing did not want to run as expected I will write down how finally it did it.
Admittedly I do not know anything about Apache, PHP and CodeIgniter as well as any viable alternative to them. However, I needed some tool for hosting personal contents and I gave them a go.
The goal was to get something extremely simple running in a robust manner. I'd like to:
- display friendly URLs
- do not use .htaccess files
- only use virtual hosts
- only use rewrite rules as URL manipulation mechanism
The first point above translates in CodeIgniter with routing and removing index.php from the requested URI. Google 'hide index.php CodeIgniter' to get a flavour of it. Once you have done that carry on reading this.
From the official docs1 this is what you've got to do:
1 2 3 4 | RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
|
It assumes you are using a .htaccess file, it also assumes you are willing to scatter dot-hidden-files across the file system, which is also discouraged by Apache folks2.
I don't want to use it, I'll move it to the vhost. In order to get it right though there are a few caveats to be noted. .htaccess lives in a directory context, so make sure this will be replicated in the vhost, as:
1 2 3 | <Directory "/var/www/html">
Require all granted # This assumes that /var/www/html can be safely accessed
</Directory>
|
Then, RewriteEngine & Co. can be added, but one more thing must be clarified:
DO NOT REDIRECT. This means, make sure R
isn't one of the flags you are
passing to the rewrite rule. This is because you want the rewrite engine to be
silently manipulating the requested URI server side only, definitely you do not
want the client to send a new request that includes index.php/whatever
.
1 2 3 4 5 6 7 | <Directory "/var/www/html">
Require all granted
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</Directory>
|
Now you can tell CodeIgniter not to expect any prefix before the controller is
invoked, in config/config.php
remove index.php
:
1 2 | - $config['index_page'] = 'index.php';
+ $config['index_page'] = '';
|
Last thing to do is to set up some route in order to map a specific requested
token to the right controller for your case. This is done in config/routes.php
as follows3:
1 2 3 | $route['blog/joe'] = 'blogs/users/34';
$route['product/(:any)'] = 'catalog/product_lookup';
$route['product/(:num)'] = 'catalog/product_lookup_by_id/$1';
|
HTH