I am sure theres a better way to do this, but cant really figure it out.
Can somebody tell me if theres a better way to write to following Apache .htaccess rewrite rules?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ /index.php?param1=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)$ /index.php?param1=$1¶m2=$2 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?param1=$1¶m2=$2¶m3=$3 [L,QSA]
If you just have 3 path segments your current code does not seem that bad. Your current rules are easy to understand, and I don't think the duplicated conditions !-f and !-d will have a huge performance impact.
You can rewrite your current rules to a sequence like this. First you rewrite the url val1/val2/val3/val4/val5 to index.php/val1/val2/val3/val4/val5. Then we have a bunch of similar rules that all take the first path segment and turn it into a parameter. Once no more path segments remain the rest of the rules are ignored.
#Only on requests with at least 1 character (e.g. not to http://localhost)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php%{REQUEST_URI} [QSA]
#Since we don't have the L flag, this will do param1 - paramx in one go
RewriteRule ^index\.php/([^/]+)(/.*)?$ index.php$2?param1=$1 [QSA]
RewriteRule ^index\.php/([^/]+)(/.*)?$ index.php$2?param2=$1 [QSA]
RewriteRule ^index\.php/([^/]+)(/.*)?$ index.php$2?param3=$1 [QSA]
RewriteRule ^index\.php/([^/]+)(/.*)?$ index.php$2?param4=$1 [QSA]
RewriteRule ^index\.php/([^/]+)(/.*)?$ index.php$2?param5=$1 [QSA]
Before using this, you should test both the performance of these rules and your current rules to see which one performs better. Please note that this approach yields strange results if more than, in this case, 5 path segments are in the url, as the 6-th until nth path segment will overwrite param1 - param5. You could 'fix' this by adding another rule RewriteRule ^index\.php index.php [END] on recent versions of Apache.
Related
I have a rewrite rule where if you type:
www.whatever.com/profile-one.php
that is the url you see, but the actual template page is:
www.whatever.com/profile.php
Here are the lines in htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)([^/])$ http://www.whatever.com/$1$2/ [R=301,L]
RewriteRule profile-(.*)\.php$ profile.php?name=$1
My problem is, if you visit a url like:
www.whatever.com/second/profile-one.php
It still tries to bring back the profile page, even though the profile.php template does not exist in the "second" directory. What would be the best way to prevent this please?
This is happening due to wrong regex here. You need to use start anchor in your 2nd rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)([^/])$ http://www.whatever.com/$1$2/ [R=301,L]
RewriteRule ^profile-(.*)\.php$ profile.php?name=$1 [L,QSA]
been looking for several hours now without success.
I'd like all urls containing /en/ to ignore this part but continue with all other rules in the htaccess (like php to no extension rule).
EXAMPLE
www.domain.com/en/gallery -> should point to gallery.php in my server root
www.domain.com/gallery -> should ALSO point to gallery.php in my server root
(will have to take care of duplicate content here somehow later)
www.domain.com/en/contact -> should point to contact.php in my root
Thank you
U P D A T E
Like mentioned in my question I'd like all other rules to still be running.
Only this rule does not work with below solution as it should work with
www.domain.com/en/category1 AND www.domain.com/category1 so with or without EN.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !(\.png|\.jpg|\.gif|\.jpeg|\.bmp|\.css|\.js|\.ico)$
RewriteRule ^([^/]+)/? /categories.php?rw=1&url=$1 [L,QSA]
Put this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(?:en/)?([^/]+)/?$ $1.php [L]
UPDATE:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !\.(png|jpe?g|gif|bmp|css|js|ico)$
RewriteRule ^(?:en/)?([^/]+)/?$ categories.php?rw=1&url=$1 [L,QSA]
Sorry about this question - I know this is asked a lot, but this case is a little more distinct (for me at least).
I have the following content in my current .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?mode=$1 [QSA,L]
This rewrites all URLs that are from index.php and have the mode parameter to a simply URL where the mode's content becomes the main part of the URL, like this:
http://someurl.com/index.php?mode=mymode
Becomes:
http://someurl.com/mymode
This is exactly what I need. But I also need to extend this and be able to achieve the same effect with another file of mine named user.php. The case is almost the same:
http://someurl.com/user.php?action=hello
Becomes:
http://someurl.com/hello
I have no idea how to achieve the second part without conflincting with the first one.
I'm kinda stuck on this one.
Keep your rules like this:
# new rules for /user.php?action=hello
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^user/([^/]+)/?$ user.php?action=$1 [QSA,L]
# existing rule for /index.php?mode=mymode
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?mode=$1 [QSA,L]
PS: Also better to use absolute path in your css, js, images files rather than arelative one. Which means you have to make sure path of these files start either with http:// or a slash /.
I want a simple redirect in my .htaccess, with the goal of making a "shortlink" to a long URL.
mydomain.com/short
to take the user to
http://www.mydomain.com/blahblah/foo/bar/foobar/uglylongurl.html
So I tried this:
Redirect /short http://www.mydomain.com/blahblah/foo/bar/foobar/uglylongurl.html
but within the same .htaccess file is:
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
This is causing my simple redirect to have "short" appended as a query string.
I have tried [R] to redirect immediately and I've also tried [L] to stop processing if the first (simplest) rule is used. Both give me a 500 error.
I hope someone knows what I'm missing here. I am on a tight deadline and this is just killing me :P Thanks in advance for any help.
Many thanks to the responder who got this working. I had the redirect above the other rules, however, I needed to change it to a RewriteRule and add the additional code as in his example.
One more issue arose after this....and with his suggestion, I am adding the next layer of the problem to this question (instead of to the comment reply, where the code tags didn't work and it was hard to read).
So here is my next issue. The first one in the list works just fine, whether redirecting to an internal page or an external URL. But subsequent rules give me a 404 error. Here is what it looks like (and note they are all before the one that appends the query string):
RewriteRule ^short/?$ /ugly/long/url.html [L,NC]
RewriteRule ^/sweet/?$ /another/ugly/long/url.html [L,NC]
RewriteRule ^/offsite/?$ http://www.somewhereelse.com/with/a/long/url.html [L,NC]
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Order of rewrite rules in pretty important. First have your desired rule then rest of the rules.
RewriteEngine On
RewriteRule ^short/?$ /blahblah/foo/bar/foobar/uglylongurl.html [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
My mission is to achieve
http://localhost/projectname/media/video
from
http://localhost/projectname/index.php?m=media&cmd=video
and also
http://localhost/projectname/home
http://localhost/projectname/index.php?m=home
Below the files helps to achieve my mission
RewriteRule ^([^/]*)$ /projectname/index.php?m=$1
RewriteRule ^([^/]*)/([^/]*)$ /projectname/index.php?m=$1&cmd=$2
the thing is that any external files such as javascript and css would not be taken into play.
i know my alternative is to put this is htaccess
RewriteRule ^([^/]*)/cmd/([^/]*)$ /projectname/index.php?m=$1&cmd=$2
which enables http://localhost/projectname/media/cmd/video
I would like to make it without the CMD. Any suggestions?
Change your rules to this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)/?$ projectname/index.php?m=$1&cmd=$2 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/?$ projectname/index.php?m=$1 [L,QSA]
And make sure your js, css, images files are using absolute path not the relative ones. Which means their paths should either start with http:// or /.
why not just pass everything to index.php and then handle/parse the path, e.g.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Then use
$_SERVER['PATH_INFO']
$_SERVER['ORIG_PATH_INFO']
$_SERVER['QUERY_STRING']
http://php.net/manual/en/reserved.variables.server.php