views:

566

answers:

5

I want requests to my site to work as follows:

http://example.com/ would pull up the index.php file (the current default behavior) ideally without displaying the index.php

http://example.com/foo.php would pull up foo.php as would be expected

http://example.com/blerg would redirect to http://example.com/bar.php?code=blerg

I have the following rewrite rules right now

    RewriteRule ^/(.*\.(php|html|htm|css|jpg))$ /$1 [NC,L]
    RewriteRule ^/(.*)$ /bar.php?code=$1 [NC,L]

which almost works, except http://example.com/ pulls up bar.php instead of index.php

Ideally I wouldn't have to have every possible file extension in the first rule, I would rather it just detect if it's an actual file.

A: 

Assuming this is in .htaccess and not the apache conf file, theres no / at the front of the first part of a rewrite rule. So if you want to map:

http://example.com/blah.jpg

you do:

RewriteRule ^blah\.jpg$ /some_other_file.jpg [L]

Note the lack of a leading / and the escaping of the period (.) otherwise it matches any character (eg without it, the rule would match blahxjpg).

Also if you're redirecting something that is otherwise a directory, you may find the client or the server puts a trailing slash. To deal with it I typically just do this::

RewriteRule ^directory/?$ /some_other_directory/index.php [L]

or similar.

That last point relates to:

RewriteRule ^/(.*)$ /bar.php?code=$1 [NC,L]

Basically change it to:

RewriteRule ^/?(.*)$ /bar.php?code=$1 [NC,L]

and I think it'll sort it out.

cletus
It depends on where you put the rule. If it's in .htaccess, you're right, but if it's in the main apache conf file, that's not the case.
Matt Kane
Good point, amended.
cletus
Thanks for the input cletus, I changed the second rule to RewriteRule ^/?(.*)$ /bar.php?code=$1 [NC,L] but I'm still getting the main request (http://example.com) redirected to http://example.com/bar.php
borkencode
A: 

Use a RewriteCond directive in front of the second rule so that it only matches the URLs you want, e.g.:

RewriteCond %{REQUEST_URI} ^/blerg$
RewriteRule ...
Matt Kane
A: 

Add a rule that intercepts the http://example.com/ request and prevents the last rule from running:

RewriteRule ^/(.*\.(php|html|htm|css|jpg))$ /$1 [NC,L]
RewriteRule ^/$ /index.php [L]
RewriteRule ^/(.*)$ /bar.php?code=$1 [NC,L]

I generally add QSA ("query string append") to my rules, as well: [QSA,L].

This rule set forces requests to non-existent files to go through a handler script:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /handler.php?request=$1 [QSA,L]
Adam Backstrom
This is very close! A request without any file name ( example.com/ )gets redirected to bar.php?code=/index.html and other calls have the slash in front of them as well.
borkencode
+2  A: 

Not exactly what you've asked for I realise, but I often use this in .htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php

..to send anything that isn't an actual file or directory to index.php, which then contains logic to interpret whatever's in the URL string.

e.g.

$url_array = split('/', $_SERVER['REQUEST_URI']);
array_shift($url_array); // remove first value as it's empty
da5id
A: 

Found a solution that works

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([^.]+)$ /bar.php?code=$1 [QSA,L]
http://example.com/ directs to index.php properly (without showing index.php)
http://example.com/abc directs to bar.php?code=abc
http://example.com/foo.php operates normally.
borkencode