How do I map path components into query parameters using mod_rewrite? - .htaccess

How would I change this:
http://www.mattvisk.com/?page=portfolio&item=rae
To this:
http://www.mattvisk.com/portfolio/rae

Try this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/(images/|css/|js/)
RewriteRule . - [S=2]
RewriteRule ^([a-z0-9_\-\.]+)/?$ index.php?page=$1 [L,NC,QSA]
RewriteRule ^([a-z0-9_\-\.]+)/([a-z0-9_\-\.]+)/?$ index.php?page=$1&item=$2 [L,NC,QSA]
Make sure mod_rewrite is enable
edit: I added the dot, poolie had a good point there.
The [S] flag is used to skip rules that you don't want to run. This can be thought of as a goto statement in your rewrite ruleset. In the following example, we only want to run the RewriteRule if the requested URI doesn't correspond with an actual file.

Related

htaccess mod rewrite confusion

I am trying to apply mod rewrites to my URL to make it nicer but I am getting caught up in all the confusion of this subject.
Please could you help me out with the following examples of what I want to do :
I want to attach any variable from the root of my site into the lyprofile.php page
# Turn mod_rewrite on
RewriteEngine On
RewriteCond %{THE_REQUEST} /(.*)
RewriteRule /(.*) lyprofile.php?us=$1
I want a url such as profile/settings to go to lysettings.php
# Turn mod_rewrite on
RewriteEngine On
RewriteCond %{THE_REQUEST} /profile/settings
RewriteRule /profile/settings lysettings.php
These two examples if working should help me to work out all my other URL's, but I can't get these to work.
Also do you need an absolute URL, as I'm working on my local machine and an absolute URL would just cause a lot of hassle. Just in case my absolute URL is http://localhost/Linku2.5/
You generally want to go from the most specific rules to the least specific. Of the two things that you want to do, the first is the least specific, as (.*) can be anything. So we have to start with the much more specific and less arbitrary /profile/settings.
If these rules are in your htaccess file (in your case, in the Link2.5 directory), you don't want a leading slash, so simply:
# you only need to turn on once
RewriteEngine On
# Don't need absolute URLs, but you may need this line:
RewriteBase /Link2.5/
RewriteRule ^profile/settings lysettings.php [L]
Then, because your other rule is so general, you need to add some conditions so that you don't cause an infinite loop (the rewrite engine will continue to loop until the URI stops changing):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ lyprofile.php?us=$1 [L,QSA]
If you know your "us" variable can only be numbers or letters, you can make the line with the rule a bit more specific:
RewriteRule ^([A-Za-z0-9]+)$ lyprofile.php?us=$1 [L,QSA]
etc.
Can you check this in vhosts config?
# Turn mod_rewrite on
RewriteEngine On
RewriteRule lyprofile\.php - [L]
RewriteCond %{REQUEST_URI} /(.*)
RewriteRule /(.*) lyprofile.php?us=$1 [L]
RewriteCond %{REQUEST_URI} /profile/settings
RewriteRule /profile/settings lysettings.php [L]

Replace all question mark and equal sign by slash?

Is there a way to replace all question mark, '&' , and equal sign by slash ???
currently I am only replacing php extensions by .html
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)\.html$ $1.php [nc]
now, if the websites url is this
http://www.mydomain.com/session/image-display.php?image=1&id=59
the user should get
http://www.mydomain.com/session/image-display.html/image/1/id/59
--edited---
I just need a example so that i could write them for other pages as well.
also how to rewrite 2 or more rewrite rules ??
Based on the example you gave, you can use this:
RewriteRule ^session/image-display.html/image/(.*)/id/(.*)
/session/image-display.php?image=$1&id=$2 [L]
The [L] at the end is optional, it tells Apache to stop looking for other rules if this one is applied
You need to change your links so that they look like:
http://www.mydomain.com/session/image-display.html/image/1/id/59
Then add this in the htaccess file in your document root, before any rules that you may already have:
RewriteCond %{THE_REQUEST} \ /session/image-display\.php\?image=([^&]+)&id=([^&\ ]+)
RewriteRule ^ /session/image-display.html/image/%1/id/%2? [L,R=301]
RewriteRule ^session/image-display\.html/image/([^/]+)/id/([^/]+) /session/image-display.php?image=$1&id=$2 [L]
Try this in .htaccess:
RewriteRule ^(.*)\.html/image/([^/]+)/id/([^/]+)$ $1.php?image=$2&id=$3 [NC]
These 2 rules will internally rewrite /session/image-display.html/n1/v1/n2/v2/n3/v3 to /session/image-display.php?n3=v3&n2=v2&n1=v1
There can be any number of /name/value pairs as this rule is pretty generic.
# this rule will be applied as many times as there are /name/value pairs in URI
# after /session/image-display.html
RewriteRule ^(session/image-display\.html)/([^/]*)/([^/]*)(.*)$ /$1/$4?$2=$3 [L,QSA,NC]
# this rule be applied in the last then all /name/value pairs have been converted
# into query string
RewriteRule ^(session/image-display)\.html/?$ /$1.php [L,NC]

.htaccess not working for a specific case

I am facing a strange issue while working with .htaccess file.
Here is my file:
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^(admin)($|/) - [L]
RewriteRule ^$ ./web/view/
RewriteRule ^([A-Za-z0-9]+)$ ./web/view/?module=$1
RewriteRule ^([A-Za-z0-9]+)/$ ./web/view/?module=$1
RewriteRule ^([A-Za-z0-9]+)/([A-Za-z0-9]+)/([0-9]+)$ ./web/view/?module=$1&id1=$2&id2=$3
RewriteRule ^([A-Za-z0-9]+)/([A-Za-z0-9]+)/([0-9]+)/$ ./web/view/?module=$1&id1=$2&id2=$3
RewriteRule ^([A-Za-z0-9]+)/([A-Za-z0-9]+)$ ./web/view/?module=$1&id1=$2
RewriteRule ^([A-Za-z0-9]+)/([0-9]+)/$ ./web/view/?module=$1&id1=$2
ErrorDocument 404 err.php
</IfModule>
Now in the last rule, if I add [a-z] along with [0-9], I am getting a 500 error. E.g., the below line will give me 500 error:
RewriteRule ^([A-Za-z0-9]+)/([a-z0-9]+)/$ ./web/view/?module=$1&id1=$2
However, if I use A-Z, it is working fine.
RewriteRule ^([A-Za-z0-9]+)/([A-Z0-9]+)/$ ./web/view/?module=$1&id1=$2
Even [NC] is also giving me same error.
Can you help me to identify and correct this problem?
Now in the last rule, if I add [a-z] along with [0-9], I am getting a 500 error. E.g., the below line will give me 500 error:
The reason is because the rewrite engine is going into an infinite loop:
request URI looks like /something/id/ (note the trailing slash)
it matches the rule: RewriteRule ^([A-Za-z0-9]+)/([a-z0-9]+)/$ ./web/view/?module=$1&id1=$2
URI gets rewritten to /web/view/?module=something&id=id
new URI is put back into the rewrite engine, new URI = /web/view/
URI matches the (same) rule: RewriteRule ^([A-Za-z0-9]+)/([a-z0-9]+)/$ ./web/view/?module=$1&id1=$2
URI gets rewritten to /web/view/?module=web&id=view
repeat from step 4
You need to add a condition to prevent it from looping:
RewriteCond %{REQUEST_URI} !/web/view
RewriteRule ^([A-Za-z0-9]+)/([A-Za-z0-9]+)/$ ./web/view/?module=$1&id1=$2
My first instinct is to add a [L] at the end of each rewrite line, for example:
RewriteRule ^([A-Za-z0-9]+)$ ./web/view/?module=$1 [L]
This works just fine since your rewrites are independent of each other.
The second step is to consolidate each group of RewriteRule directives where the forward slash (/) is optional, so instead of:
RewriteRule ^([A-Za-z0-9]+)$ ./web/view/?module=$1
RewriteRule ^([A-Za-z0-9]+)/$ ./web/view/?module=$1
It is just as safe to say:
RewriteRule ^([A-Za-z0-9]+)/?$ ./web/view/?module=$1
The question mark (?) means 0 or 1 but not more than the preceding character, group or expression.
Lastly you may consider optimizing the group of RewriteRule directives:
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^(admin)($|/) - [L]
RewriteRule ^$ ./web/view/ [L]
RewriteRule ^([A-Za-z0-9]+)/?((([A-Za-z0-9]+)/?)?(([A-Za-z0-9]+)/?)?)?$ ./web/view/?module=$1&id1=$4&id2=$6 [L]
ErrorDocument 404 err.php
</IfModule>
And as bonus information, it may be worth your while to use the QSA (query string append) flag, for example:
RewriteRule ^$ ./web/view/ [L,QSA]
You may also consider using gskinner's RegExr tool to help you create, test or troubleshoot your regular expressions.
Lasty, in your .htaccess file, depending on how the AllowOverrides directive is defined, you may be able to turn on mod_rewrite logging:
RewriteLog "/path/to/your/home/dir/rewrite.log"
RewriteLogLevel 4
However, depending on your apache server version or configuration, you may be required to use the per-module logging configuration since RewriteLog/Level is deprecated:
LogLevel alert rewrite:trace4
As a disclaimer, this level of logging will slow down your webserver, so do not enable it for too long nor on a production environment.

.htaccess mod_rewrite won't skip RewriteRule with [S]

As an FYI, I am using the following .htaccess file in located at www.site.com/content/
When a user visits www.site.com/content/login I want it to display the content from www.site.com/content/userlogin.php (masked via rewrite, and not redirect) - which I have done SUCCESSFULLY like so:
RewriteEngine On
RewriteBase /content/
RewriteRule ^login/?$ /content/userlogin.php [NC,L]
However, I would like to add the follwoing: If they try to access www.site.com/content/userlogin.php directly, I want them to get redirected to a 404 page at www.site.com/content/error/404.php
RewriteEngine On
RewriteBase /content/
RewriteRule ^login/?$ /content/userlogin.php [NC,S=1,L]
RewriteRule ^userlogin\.php$ /content/error/404.php [NC,L]
With that in the .htaccess file, both www.site.com/content/login and www.site.com/content/userlogin.php show www.site.com/content/error/404.php
First the S=1 will have no function as the L directive will make any further rewriting stop.
It seems like the first RewriteRule makes Apache go through the .htaccess rules one more time, so you need to know if the first rewrite has happend. You could do this by setting an environment variable like this:
RewriteRule ^login/?$ /content/userlogin.php [E=DONE:true,NC,L]
So when the next redirect occurs the Environment variable actually gets rewritten to REDIRECT_<variable> and you can do a RewriteCond on this one like this:
RewriteCond %{ENV:REDIRECT_DONE} !true
RewriteRule ^userlogin\.php$ /content/error/404.php [NC,L]
Hope this helps
Use %{THE_REQUEST} variable in your code instead:
RewriteEngine On
RewriteBase /content/
RewriteRule ^login/?$ content/userlogin.php [NC,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+userlogin\.php[\s\?] [NC]
RewriteRule ^ content/error/404.php [L]

QUERY_STRING in .htaccess While redirecting

How can I allow visitors to use this link (www.example.com/news?id=34) in order to see (www.example.com/index.php?page=news&id=34)
Right now I am hiding the extensions of my PHP files in order to make the links look nice. When visitors go to (www.example.com/news) they can see the page (www.example.com/index.php?page=news). However, when they go to (www.example.com/news?id=12) they get a 404 error.
At this point, PHP does not recognize the id parameter. Here is what I currently have in my .htaccess file
Options +FollowSymlinks
RewriteEngine on
# catch request with no querystring like /Home
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^([^/]+)$ /index.php?page=$1 [L]
# make other requests with a non-empty query string go to /index.php?id=XXXXX
RewriteCond %{QUERY_STRING} ^.*$
RewriteRule ^$ /index.php?id=$1 [QSA,L]
Your second test pattern (^$) only matches the case where the user doesn't put any path information in, but does include a query string (e.g. www.example.com/?id=12). Also note that the backreference $1 has no value in that rule either.
The simplest solution is to just combine the two rules, since you can use the QSA flag to do the work of appending the id=# part for you:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ /index.php?page=$1 [QSA,L]
The condition of your first rule fails as the query is not empty. Try it without that condition but with the following condition instead:
RewriteCond $1 !=index.php
RewriteRule ^([^/]+)$ /index.php?page=$1 [L]

Resources