views:

3619

answers:

4

I'm running a LAMP environment with CodeIgniter. I want to be able to use its URL pattern, like, http://localhost/controller/function/ID, but by default it has to be http://localhost/index.php/controller/function/ID. The user guide says that I need a .htaccess file to make the former style possible, and uses this as an example:

RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

But I don't understand how this works. Where should I put the .htaccess? Does it have to be in the server root?

What if I have multiple sites running on my server. Do I have to put it in /var/www/ and specify conditions based on what directories are loaded? Or can I just put it in /var/www/site_using_codeigniter/? I'm not sure how to even get this to work.

Can I make it so that it will only map to an MVC URL if the requested URL doesn't actually exist? For example, http://localhost/articles/2009/some-article-name wouldn't be a directory on the server, so it would map to index.php and be given to codeigniter, but http://localhost/forum would exist on the server but shouldn't be handled by codeigniter.

Any other things I should do with a .htaccess file? Anything good to read about them?

update

I changed my config file like this:

$config['index_page'] = ""; //used to be "index.php"

and added this to a .htaccess file:

RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

and saved it in my sites root directory (in this case /var/www/cms/)

I went into /etc/apache2/conf.d/security (which is included by /etc/apache2/apache2.conf) and did this:

<Directory />
    AllowOverride All #was "none", but this was all commented out
    Order Deny,Allow
    Deny from all
</Directory>

It's still not working however. If I navigate to http://localhost/cms/index.php/hello, it prints "Hello there," but http://localhost/cms/hello gives a 404 error.

Ideas?

update: græt success!

I had to dig through my apache configuration files to finally find where all the directories were defined (I had never messed around in server config files before this date) and found that pesky AllowOverride None that was foiling my plans for greatness.

Now it works perfectly. All of the answers here are viable and work.

+1  A: 

Put that at the document root of your Web site.

If you have multiple sites, put it at the top of each such site.

If you have multiple sites running from the same directory, you can use a RewriteCond to exclude or include particular sites to the rewrite rule.

You can exclude certain directories (eg /articles) the same way.

cletus
+3  A: 

In your system/application/config/config.php, change

$config['index_page'] = "index.php";

to

$config['index_page'] = "";

and in your .htaccess, add this:

RewriteEngine on
RewriteCond $1 !^(index\.php|images|stylesheets|scripts|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

Add your .htaccess file to the same directory where the system folder is located, so in your CodeIgniter root directory, you should have

  • system/
  • user_guide/
  • index.php
  • .htaccess
  • license.txt

Also, since you have multiple sites running on your server, you might want to have VirtualHosts. Add this to the last part your apache2.conf for each site that you have:

Listen *:11000
<VirtualHost *:11000>
     ServerAdmin [email protected]
     DocumentRoot "/var/www/cms"
     ServerName you-dummy.com
     <Directory "/var/www/cms">
          AllowOverride All
          Options +Indexes
          DirectoryIndex index.php
          Order allow,deny
          Allow from all
     </Directory>
     ErrorLog logs/cms_log
     CustomLog logs/cms_log common
</VirtualHost>

You may now access the site from http://localhost:11000/ and access the controller using http://localhost:11000/hello.

Randell
but the .htaccess is in `/var/www/cms/`, and I configured the base URL to be `http://localhost/cms`. In any case, neither of the URL's work
Carson Myers
this makes it refuse the connection, same with if I change the port to 80 too. I must be doing _something_ horribly wrong, I don't think it's normally this difficult to do this.
Carson Myers
What OS are you using?
Randell
Ubuntu linux. But you know what, instead of everything being in one "httpd.conf" file it's spread throughout a bunch. I figured since nothing at all was working I went digging through all the config includes and found where the directories were defined, and changed AllowOverride there. It doesn't work yet but I'm going to try everything again now that the .htaccess is actually getting opened.
Carson Myers
I've read your answer. Yeah, that `AllowOverride` set to `None` is not easy to catch. You only get to modify it almost only once for each installation so it's often forgotten.
Randell
+1 Randell your right. I had that the same problem that fixed it out. My thanks.
Fábio Antunes
+1  A: 

This particular .htaccess file looks like it needs to go in your site's root (meaning, the currently executing site.)

Look into the documentation for RewriteCond to learn about what other kinds of conditions you can specify. Basically a RewriteRule will only be applied if all of its preceding RewriteConds are matched. You could try adding these rules to only redirect if the requested URL does not exist:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

mod_rewrite is very powerful, but it can be a real pain if it's not doing what you think it should. I don't know of any way to debug its directives, either.

As far as what else you can do with a .htaccess file, the Apache docs for htaccess files are always a good place to start. The most common use is for per-directory authentication. Most server configuration directives are supported in a .htaccess file (provided that the server's AllowOverride says so), but some have different syntax.

jnylen
A: 
<IfModule rewrite_module>
RewriteEngine on
RewriteBase /

# Removes the "/" at the end
RewriteRule (.+)/$ /$1 [L,R]

RewriteCond $1 !^(index\.php|dhtml|img|css|js|favicon\.ico|robots\.txt)
RewriteRule ^([^?&]+) /index.php/$1 [L]
</IfModule>
w35l3y
I also pasted this in my httpd.conf file, with no luck.
Carson Myers
this is what I use :/ and it works fine
w35l3y