htaccess mod_rewrite part of url to GET variable - php

I have some URLs like these:
http://plutov.by/post/cubique_zf_jquery
http://plutov.by/post/mysql_useful_queries
How can I with help of Apache mod_rewrite open the next pages?
http://plutov.by/post/main?title=cubique_zf_jquery
http://plutov.by/post/main?title=mysql_useful_queries
Also, will be this new rewrite rule work with "one entry point rewriting"?
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
Thanks.

To make the new rewrite rule work with "one entry point rewriting", have your rewriteRules like this:
The QSA flag is mandatory as you are adding a new query string.
RewriteEngine On
RewriteRule ^(post)/([\w\d\-]+)/?$ $1/main?title=$2 [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . index.php [L]
Flag QSA Apache Docs.
!-l checks that the requested URI is not a symbolic ink.

You can use something like this in your .htaccess:
RewriteRule ^post/(.*)$ post/main?title=$1 [L]
You should keep this rule BEFORE one entry point rewriting rules. If rule will trigger then rewrite rule lookup will be finished (since [L] option specified)
Some modification of paths may be required if you want to use these rules in VirtualHost context

Related

htaccess rewrite url error page and id

I want to achieve the following
Any links like mydomain.com/anyword should be rewritten to index.php?pg=$1
example:
mydomain.com/new -->index.php?pg=new
mydomain.com/purchased -->index.php?pg=purchased
mydomain.com/login -->index.php?pg=login
Any links like mydomain.com/anyword/anynumber should be rewritten to index.php?pg=$1&id=$2
example:
mydomain.com/new/12 -->index.php?pg=new&id=12
mydomain.com/purchased/240 -->index.php?pg=purchased&id=240
mydomain.com/login/10 -->index.php?pg=login&id=10
I have used the following htaccess code.
The first one works properly.
Regarding the second one, the entire parameter is passed to pg and there is no parameter id at all.
That is in case of url
mydomain.com/purchased/240
in my php $_Get has only 'pg' parameter and 'id' parameter at all
and pg=/purchased/240
Please suggest the proper way to do it.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?pg=$1 [NC,QSA]
RewriteRule ^([^/]+)/(\d+)/.*$ /index.php?pg=$1&id=$2 [NC,QSA]
Thanks
EDIT: Correct solution in case anyone made need it
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+) /index.php?pg=$1&id=$2 [NC,L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?pg=$1 [NC,QSA]
This is because of the catch-all pattern. (.*) matches everything and rewrites it to the target. For your example, your first rule matches both requests, /foobar/ and /foobar/123 are rewritten to /index.php?pg=request . To fix this, you need to fix the order of your rules, you need to put your specific rule before the catch-all rule :
RewriteRule ^([^/]+)/(\d+)/?$ /index.php?pg=$1&id=$2 [L]
RewriteRule ((?!index.php).+) /index.php?pg=$1 [L]

Multilanguage and mod_rewrite

I have a multilanguage website. I want the URL's to be like: http://example.com/en/blog_post/2 where blog_post is the name of the file blog_post.php and 2 is value of the parameter id.
I have this .htaccess code now
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/(.*)$ /$2?lang=$1 [L]
RewriteRule ^(bg|en)/(.*)/([^/.]+)$ /$2?lang=$1&id=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
I tried with this line, but it doesn't work:
RewriteRule ^(bg|en)/(.*)/([^/\.]+)$ /$2?lang=$1&id=$3 [L]
Can you help me please :)
I did it. It works with these lines. Thanks to everyone :)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/post/([^/\.]+)$ blog_post.php?lang=$1&id=$2 [L]
RewriteRule ^(bg|en)/(.*)$ $2?lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) $1.php [L]
As mentioned above, the order of these directives is important. The more specific rules should come before the more general rules and this is a key problem with the above. However, the pattern also needs to be changed (made more specific) to prevent other malformed URLs triggering a 500 Internal Server Error and breaking your site. eg. /en/blog_post/2/3 (an additional - erroneous - /something) would still trigger a 500 error in the "fixed" code above.
So, this could be written as:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(bg|en)/([^/.]+)$ /$2?lang=$1
RewriteRule ^(bg|en)/([^/.]+)/([^/.]+)$ /$2?lang=$1&id=$3
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule (.*) /$1.php [L]
The generic (.*) pattern has been replaced with ([^/.]+) to only match path segments (excluding a slash). By doing this it also means that the order no longer matters and /en/blog_post/2/3 will simply result in a 404.
I've also removed the L flag on the initial RewriteRule directives, since you need to continue anyway to append the .php extension.
The RewriteRule substitutions should also be kept as root-relative, ie. starting with a slash. (Or you should include the RewriteBase directive.)
I've also added another RewriteCond directive to make sure that <file>.php actually exists before appending the file extension. If you don't do this and <file>.php does not exist then you will get another 500 error.
You could combine the two RewriteRules into one if you don't mind having an empty id= parameter (which presumably your script handles anyway):
RewriteRule ^(bg|en)/([^/.]+)(?:/([^/.]+))?$ /$2?lang=$1&id=$3
This handles both /en/blog_post and /en/blog_post/2 requests.

.htaccess $_GET-Redirection didn't work

I will redirect this url with help from mod_rewrite
http://www.example.org/site/asd
to
http://www.example.org/index.php?site=asd
On my webserver, mod_rewrite is enabled, but my example didn't works: (.htaccess)
RewriteEngine on
RewriteRule ^(.*)/site/$ index.php?site=$
it makes nothing, no fail but it didn't works.
Lets break it down
RewriteRule ^(.*)/site/$ index.php?site=$
The rule is only going to match urls like:
http://example.com/yada/yada/site/
http://example.com/something/site/
Which is backwards to what you want, so use a rule like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^site/(.*)$ index.php?site=$1 [L,QSA]
Which will match rules like:
http://example.com/site/yada/yada/
http://example.com/site/something/site/
http://example.com/site/no/slash
http://example.com/site/with/params/?abc=efg
Try rewriting as,
RewriteRule ^(.*)/site/([a-z]+)$ index.php?site=$1 [L]

Rewrite rule ignoring /index

I have simple .htaccess with:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(?!/static/).+ [NC]
RewriteCond %{REQUEST_URI} ^(?!/media/).+ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 [L]
Everything works properly (page/edit, users/show ...), but when I open browser on URL index/something a will get empty $_GET.
Where can be problem please?
Your current rewrite rule doesn't take the case of /index/something into account. If you were to just use /something then it would be redirected to index.php?query=something. Try adding this rule:
RewriteRule ^index/(.*)$ index.php?query=$1 [L]
EDIT:
Based on the comments we're seeing that Apache is using /index as an alias for /index.php. As a temporary workaround until you figure out the needed changes for the Apache configuration you could probably do:
RewriteRule ^index/(.*)$ index.php?query=index/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 [L]
Putting that first rule ahead of the RewriteCond lines will catch the /index case and the rest will be caught by your original rules.
It might be an issue with the Server config as "index" might be the default file. So the routing is being done due to the configuration and not due to the htaccess.
Try checking what file names are treated as valid default names by Apache. Also, what happens if you add /index(.*) as a separate RewriteRule?

Rewriting a URL - 2 variable without altering current rewrites

I've got most of the rewrites I need working but I can't get the second part working with 2 variables, here is my code:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ entity.php?vanityName=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/([^/]*)$ /entity.php?vanityName=$1&section=$2 [L]
The last bit needs to allow, for example, http://example.com/vanityName/Section however it doesn't pass the section variable.
How can I fix this while retaining the current rewrites?
How can I get it so it works for /vanityName, /vanityName/section but allows me to keep other directories free of rewriting, like /includes/?
You can add an extra rule for every directory you don't want to rewrite:
RewriteRule directoryName/? - [L]
If you write these rules directly after RewriteBase /, no other rules will be checked.

Categories