I'm using .htaccess for the first time and I'm encountering a loop problem. I'm trying to achieve the following:
http://something.com rewrites to http://something.com/main
http://something.com/anything rewrites to http://something.com/index.php?page=anything
So far my current attempt looks like this, which works satisfactorily:
RewriteEngine on
RewriteBase /
RewriteRule ^/?$ /main [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?page=$1 [NC,L]
However, I would like to remove both rewrite conditions to also allow requests to http://something.com/index.php to become http://something.com/index.php?page=index.php. Removing the two RewriteCond lines results in a loop and the rewrite doesn't work.
What am I doing wrong and how can I fix the problem? Thanks!
You can remove those conditions but you would need to reverse your rules and remove leading / from target URIs:
RewriteEngine on
RewriteBase /
RewriteRule ^(.+)$ index.php?page=$1 [QSA,L]
RewriteRule ^/?$ main [L]
Also remember that now your first rule will also rewrite css/js/image requests to index.php?page=.... If you want to avoid that then add this condition before first RewriteRule:
RewriteCond %{REQUEST_URI} !\.(?:jpe?g|gif|bmp|png|ico|tiff|css|js)$ [NC]
Related
I have all of my customers sites in a directory on my subdomain:
customers.example.com/sites/customer_name
I want to rewrite the url so my customers only need to write
customers.example.com/customer_name
I have tried some different htacces scripts but none of them works. And one of them gives me a error 500 internal server error, so my mod_rewrite is active
Here is my current .htaccess file:
RewriteEngine On
RewriteRule ^sites/(css|js|img)/(.*)?$ /$1/$2 [L,QSA,R=301]
RewriteRule ^(.*)$ /sites/$1/ [QSA,L]
Since the rewrite engine loops, this pattern ^(.*)$ will blindly match everything, including your rule's target: /sites/something. It'll continue to append /sites/ to the front of the URI until you end up with something like /sites/sites/sites/sites/sites/sites/sites/ etc.
You need to add some conditions to prevent the looping, something like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /sites/$1/ [L]
or
RewriteCond %{REQUEST_URI} !^/sites/
RewriteRule ^(.*)$ /sites/$1/ [L]
or
RewriteCond %{DOCUMENT_ROOT}/sites%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/sites%{REQUEST_URI} -d
RewriteRule ^(.*)$ /sites/$1/ [L]
This should work… If understand your end goal correctly. But unclear if you want the content accessible from customers.example.com/sites/customer_name and customers.example.com/customer_name at the same time:
RewriteEngine on
RewriteRule ^/sites/(.*)$ http://customers.example.com/$1 [L,R=301]
I'm having trouble rewriting the subfolder back to the file.
The redirect works but not the last rule.
Here's what I'm trying to do:
domain.com/file.php?lang=fr
would like to rewrite it back to
domain.com/fr/file.php
no matter what folder the files are in.
I'm only using one language which is french.
RewriteCond %{QUERY_STRING} ^lang=([A-Za-z-]+)/?$
RewriteRule ^(.*)\.php$ %1/$1.php? [NS,R=301,L]
RewriteRule ^fr/(.*)\.php/?$ $1.php?lang=fr&redirect=no [QSA,L]
my current htaccess file:
RewriteEngine On
RewriteBase /domain.com
RewriteCond %{QUERY_STRING} (^|&)lang=([A-Za-z-]+)(/?$|&)
RewriteCond %{QUERY_STRING} !(^|&)redirect=noneed($|&)
RewriteRule ^(.*)\.php$ %1/$1.php? [NS,R=301,L]
RewriteRule ^fr/(.*)\.php/?$ http://localhost/?$1.php?lang=fr&redirect=noneed [QSA,L]
The 1st rule is more powerful then second, so to solve your issue you have to write second at 1st place.
why not use a system like that:
RewriteRule ^(fr|en|es)/(accueil|home|bienvenida)/$ /index.php?lang=$1&act=index[QSA,L]
Try adding the RewriteBase option:
RewriteRule On
RewriteBase /
RewriteCond %{QUERY_STRING} ^lang=([A-Za-z-]+)/?$
RewriteRule ^(.*)\.php$ %1/$1.php? [NS,R=301,L]
RewriteRule ^fr/(.*)\.php/?$ $1.php?lang=fr&redirect=no [QSA,L]
(or if you don't want that option append a / at the beginning of all paths)
Also, your RewriteCond doesn't seem to handle the query string correctly, any additional parameters will cause your first rule to fail. Do this instead (I am still thinking):
RewriteRule On
RewriteBase /
RewriteCond %{QUERY_STRING} (^|&)lang=([A-Za-z-]+)(/?$|&)
RewriteCond %{QUERY_STRING} !(^|&)redirect=noneed($|&)
RewriteRule ^(.*)\.php$ %2/$1.php? [NS,R=301,L]
RewriteRule ^fr/(.*)\.php/?$ $1.php?lang=fr&redirect=noneed [QSA,L]
I have a setup that sets variables for the index page, but it also does the same for directories and I don't want it to do that. Here's my .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(login|images|favicon\.ico|home|about|sitemap|contactus|termsandconditions|privacypolicy|signup|search|careers|error|css|js) [NC]
RewriteRule ^([a-zA-Z0-9]+)$ index.php?name=$1
RewriteRule ^([a-zA-Z]+)/$ index.php?name=$1
RewriteRule ^([a-zA-Z]+)/([a-zA-Z0-9_]+)$ index.php?name=$1&page=$2
RewriteRule ^([a-zA-Z]+)/([a-zA-Z0-9_]+)/$ index.php?name=$1&page=$2
RewriteRule ^php/$ error/
Now, with this setup, if I type in mysite.com/login it will redirect to the index.php page and set login as the name variable. How do I make it to where it ignores the directories? This is frustrating me and I've looked through this site for over an hour for an answer and can't find a similar question (I might suck at that too, though. haha!).
Also, if you look at the last RewriteRule, you can see that I'm trying to redirect any attempt to access my php/ folder to my error/ folder. This is also not working.
RewriteCond only applies to the immediately following RewriteRule. Also, you can combine lines 3&4, and 5&6 respectively, by using /? on the end, which makes the / optional (regex).
Your file could be similar to this:
RewriteEngine On
#the following line will not rewrite to anything because of "-", & stop rewiting with [L]
RewriteRule ^(login|images|favicon\.ico|home|about|sitemap|contactus|termsandconditions|privacypolicy|signup|search|careers|error|css|js)/?(.*)$ - [L,NC]
RewriteRule ^php/?(.*)$ error/ [L,NC]
RewriteRule ^([^/]+)/?$ index.php?name=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?name=$1&page=$2 [L]
You may be interested in the Apache Mod_Rewrite Documentation.
RewriteCond %{REQUEST_URI} !^/(login|images|favicon\.ico|home|about|sitemap|contactus|termsandconditions|privacypolicy|signup|search|careers|error|css|js) [NC] !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
to either not execute the rule on a directory or a file
More info on the mod_rewrite documentation pages, search for CondPattern
I have these rules and I can't figure out why one of them won't work:
RewriteEngine On
RewriteBase /
Options +FollowSymlinks
Options -MultiViews
Options -Indexes
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^error/([^/.]+)/([^/.]+)$ /pages/error.php?$1=$2 [NC,R]
RewriteRule ^([^/.]+)$ index.php?user=$1 [NC,L]
RewriteRule ^([^/.]+)/.* index.php?$0 [PT]
RewriteRule ^error/.* error.php/?$0 [PT]
Rule 1 works, echo $_GET['user'] then I get results
Rule 2 works as well. If I do a print_r($_SERVER['REQUEST_URI']) then I get what ever is after .com/.
so That makes me think that its catching correctly, and if I do a as well.
So those rules seem to be working... but now if I enter
domain.com/error/access/notallowed then I get a Not Found error, so that means that my Rule 3 that wants to catch anything that starts with error isn't working.
Any ideas on what may be causing this behavior?
EDIT: updated rules based on answer
RewriteRule ^([^/.]+)$ index.php?user=$1 [NC,L]
RewriteCond %{REQUEST_URI} ^/error/?
RewriteRule ^([^/.]+)/?.* index.php?$1 [PT]
RewriteRule ^(error/?.*)$ /_msp/pages/error.php/?$1
The problem is that your second RewriteRule is catching domain.com/error/access/notallowed before apache is able to make it to the third RewriteRule. So, apache says, "I've got a rule that matches, I'm finished here," and throws away the rest of your RewriteRules. If only there were a way we could tell apache to ignore the second rule in specific cases ...
Say hello to RewriteCond
"Wait, are you saying what I think you're saying? I can tell apache to ignore that second rule?"
"Yes, that's exactly what I'm saying."
RewriteRule ^([^/.]+)$ index.php?user=$1 [NC,L]
RewriteCond %{REQUEST_URI} !^/error/?
RewriteRule ^([^/.]+)/?.* index.php?$1 [PT]
RewriteRule ^(error/.*)$ index.php?$1 [PT]
See that RewriteCond line just before your second rule? You can insert any number of conditions and they will apply to the next evaluated rule. So, in this specific RewriteCond we're telling apache that the following rule shouldn't be used if the REQUEST_URI starts with /error/.
The rewritten URL using the above rules for the address domain.com/error/access/notallowed will be:
index.php/?error/access/notallowed
You can adjust the regex according to your needs.
I believe if you switch the last two it should work:
RewriteRule ^error/.* error.php/?$0 [PT]
RewriteRule ^([^/.]+)/.* index.php?$0 [PT]
RewriteRule ^([^/.]+)/.* index.php?$0 [PT] rule is matching the url, I believe rewriting it and passing it through as the index.php, but I am not a htaccess expert.
I have an url which is http://www.urlbookmarking.com/bookmarks-details.php?bid=55
and I want it to be like
http://www.urlbookmarking.com/bookmark/55
I wrote in my htaccess:
RewriteEngine on
RewriteRule /bid/(.*) bookmarks-details.php?bid=$1
But when I go to the first URL the rewrite engine does not apply my rule. Is there any mistake, or conflict somewhere?
My full htaccess file written as follows
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteEngine on
RewriteCond %{HTTP_HOST} ^urlbookmarking.com [NC]
RewriteRule ^(.*)$ http://www.urlbookmarking.com/$1 [L,R=301]
RewriteEngine on
RewriteRule /bid/(.*) bookmarks-details.php?bid=$1
Please help me.
The line Options +FollowSymLinks is optional if already configured in httpd.conf
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^urlbookmarking\.com [NC]
RewriteRule ^(.*)$ http://www.urlbookmarking.com/$1 [R=301, L]
RewriteRule ^bookmark/([0-9]+)$ bookmarks-details.php?bid=$1 [NC, L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
A few things:
RewriteEngine On only needs to called once, though this may not be causing any problems
I also have RewriteBase / after my RewriteEngine On line
My rewrite rule looks like this: RewriteRule ^common/(.*)$ common.php?file=$1 [QSA,L], which tells me that your rule should looke like this RewriteRule ^bookmark/(.*) bookmarks-details.php?bid=$1 [QSA,L]
you should use only one RewriteEngine on
RewriteRule /bid/(.*) bookmarks-details.php?bid=$1 - put this line after Options +FollowSymLinks
Try again
Do you want you url to be /bid/55 or /bookmark/55? because you have written it as if it is going to be /bid/55...
Anyway, your .htaccess should look more like this:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^urlbookmarking.com [NC]
RewriteRule ^(.*)$ http://www.urlbookmarking.com/$1 [L,R=301]
RewriteRule ^bid/(.*)$ bookmarks-details.php?bid=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
...without the multiple RewriteEngine on directives (these don't break anything but are unnecessary), and without the leading forward slash on the bid rewrite rule. Also, put your new rule before the rules that rewrites for non-existent file so it doesn't rewrite your URL before you get a chance to use it, and add a [L] flag to the rule so it doesn't get further modified by the other rules. Also, add the line start/end markers (^/$) to the rule.
You would only use the leading forward slash if you were putting the rules in httpd.conf, you don't use them in .htaccess files.
If you want your urls to be /bookmark/, just replace bid with bookmark.
This should redirect all '/bookmarks-details.php\?bid=(id)' urls with bookmarks ids (that have only numbers) to /bookmark/(id).
RewriteRule ^/bookmarks-details\.php\?bid=([0-9]+) /bookmark/$1 [R, NC, L]
Once you successfully rewritten the URL, you then need to write a companion rule to process it, like so:
RewriteRule ^/bookmark/([0-9]+) /bookmarks-details\.php\?bid=$1 [NC, L]
If should go between the rule that always adds 'www' to the beginning and the catch all rule, which I placed at the end. All together, it may look like so:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^urlbookmarking.com [NC]
RewriteRule ^(.*)$ http://www.urlbookmarking.com/$1 [L,R=301]
RewriteRule ^/bookmarks-details\.php\?bid=([0-9]+) /bookmark/$1 [R, NC, L]
RewriteRule ^/bookmark/([0-9]+) /bookmarks-details\.php\?bid=$1 [NC, L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
This link may make things clearer: http://corz.org/serv/tricks/htaccess2.php