How to implement URL rewriting two rules with the same extension? - php

My htaccess code:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)-([0-9]+)\.html$ post-details.php?post_id=$2 [L]
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.html$ post-details-year.php?post_year=$1&post_month=$2 [L]
The first rule is working and giving me the correct output but the second one is not; it jumped to the first rule with "post_details.php" desired "Post-details-year.php".
Additionally when I change the file extension:
Example:
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.html$ post-details-year.php?post_year=$1&post_month=$2 [L]
to
RewriteRule ^post-year-([0-9]{4})-([0-9]+)\.cgi$ post-details-year.php?post_year=$1&post_month=$2 [L]

the rewriting engine starts going over the your rules one by one until it find one that fits.
The problem was that your first rule was very powerful, and it catched URLs you didn't want it to.
When you try and access post-year-123.html, the first rule matches post-year to ([a-zA-Z0-9_-]+) part of the regex, and 123 to ([0-9]+), which then just redirects you according to the first rule.
If you switch them, and put the second rule first, it will first try to match it and will success, thus sending you to the place you want.

Related

.HTACCESS adding to slugs

So, I'm currently building a REST API in PHP.
I managed to get slugs working for the most part.
If I request /api/admin/v1/users/1, it will return the user I need.
However, I also need to be able to add to it, e.g. /api/admin/v1/users/1/keys.
The HTACCESS file managing the slug is in the folder itself (/users/).
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [L]
I tried adding another line, but I think I messed up (I'm not that advanced with HTACCESS)
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
This didn't do anything, it still returns the user object.
RewriteRule ^(.*)$ user.php?slug=$1 [L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [L]
The first rule matches everything, so the second rule is never processed. But since the first rule matches everything it will also rewrite itself (to user.php?slug=user.php) on the second pass by the rewrite engine.
You can resolve these issues by making the regex more restrictive. From your example URL it looks like the slug is numeric - in which case you can restrict the regex to match digits (0-9) only.
For example:
RewriteRule ^(\d*)$ user.php?slug=$1 [L]
RewriteRule ^(\d+)/keys$ keys.php?slug=$1 [L]
Note that the first rule also matches an empty URL-path, ie. no slug at all (as does your original rule). The second rule does not permit an empty slug (it would never match anyway).
The second rule don't work because the L flag stay for: last - stop processing rules
So you need to edit to:
RewriteEngine On
RewriteRule ^(.*)$ user.php?slug=$1 [QSA, L]
RewriteRule ^(.*)/keys$ keys.php?slug=$1 [QSA, L]

htaccess 3 different urls in one php file

I have 3 step in one php file:
This is my htacess now:
RewriteRule ^igra/(.*)$ "/index.php?page=igra&id=$1"
RewriteRule ^igra/(.*)/sezona/(.*)$ "/index.php?page=igra&id=$1&season=$2"
RewriteRule ^igra/(.*)/sezona/(.*)/liga/(.*)$ "/index.php?page=igra&id=$1&season=$2&league=$3"
When i go in browser something like index.php?page=igra&id=$1 or index.php?page=igra&id=$1&season=$2 or index.php?page=igra&id=$1&season=$2&league=$3 sure with real values it works fine, but when i try to access with this pretty links it always show me the first rewrite rule..
I hope u understand me what i need here, best regards..
Your first rule is capturing everything, so the subsequent rules never get executed. Just switch them around:
RewriteRule ^igra/(.*)/sezona/(.*)/liga/(.*)$ /index.php?page=igra&id=$1&season=$2&league=$3 [L]
RewriteRule ^igra/(.*)/sezona/(.*)$ /index.php?page=igra&id=$1&season=$2 [L]
RewriteRule ^igra/(.*)$ /index.php?page=igra&id=$1 [L]
Notice also the addition of the L flag.

Unable to solve .htaccess url rewriterule, gives 404 for all pages

I want to show URL like below examples:
1) http://www.domainname.com/detail/name/123.html
2) http://www.domainname.com/detail/124.html
In both URLs I want to show if "name" exist then want to display URL with "name" otherwise without "name".
1) RewriteRule ^detail/(.*).html$ detail.php?id=$1 [QSA]
2) RewriteRule ^detail/(.*)/(.*).html$ detail.php?id=$2 [QSA]
First rule is working file without "name". Second rule is not working and gives 404 for all pages.
Thanks in Advance.
You can use just one rule to handle both cases:
RewriteRule ^detail/(?:[^/]+/)?([^./]+)\.html$ detail.php?id=$1 [L,NC,QSA]
The problem you are having, is that the first rule matches both your first and second case. Obviously when id is name/123 your application can't handle it. What you want to do is limiting the characters to non-slash characters. After all, that means it can only match the last path segment. Besides that, force yourself to always escape literal dots in a regex. A dot matches pretty much anything if you don't do that...
RewriteRule ^detail/([^/]+)\.html$ detail.php?id=$1 [QSA,L]
RewriteRule ^detail/[^/]+/([^/]+)\.html$ detail.php?id=$1 [QSA,L]

Rewriting url having more than one url parameter

Has been researching on how to rewrite url using htaccess file. After much time invested, I still have very vague idea of how a url will be rewritten.
Basically, I have a url:
http://mehthesheep.com/bali/jimbaran/blue-point/1
I would like to rewrite to:
http://mehthesheep.com/countries/hotel.php?hotel_id=1&state=bali&city=jimbaran
How do I go about having more than one parameter in the url?
Any help with some simple explanation would be appreciated!
So apache isn't my strongest skill, but from what I understand the way you would rewrite the urls is with mod rewrite, and in your regex, each matching parameter can be mapped to something else. So something like:
#1st field #match 2
RewriteRule ^/hotel/(.*)/(.*) http://www.example.com/hotel.php?hotel_id=$2&state=$1 [NC,QSA,L]
#2nd field #match 1
My syntax might be wrong so I apologize, but the gist is that I can take patterns and then correspond the matches to '$n' keys in my rewrite url. In the above example a call to /hotel/bali/1 would rewrite to hotel.php?hotel_id=1&state=bali. Not sure if it matters, but I used a very simple match '(.*)' basically means anything.
The last bit w/ are flags you can add to make sure you get the desired behavior. QSA allows for a querystring to be attached in case you had tracking or other params come in, NC makes the matching case insensitive, in the event they try something like /Hotel. L is for last, meaning if the rule is matched this is the last rule to evaluate so execute the rewrite (or something to that effect).
Hope that helps. This really helped me dig into mod rewrite:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
Put this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ /countries/hotel.php?hotel_id=$4&state=$1&city=$2 [L,QSA]

htaccess not reading php file

I seem to be lost in a big pile of code. I have the following piece of .htaccess code:
RewriteRule ^user/(.*)$ index.php?p=user/$1 [L]
RewriteRule ^user/(.*)/(.*)$ index.php?p=user/$1&id=$2 [L]
Now, I have a file called profile.php, inside that I use $_GET to get the ID. But when I go to /user/profile/1, it does nothing. When I go there without a ID, my script works. Can somebody help me out and tell me what I am doing wrong?
Thank you. Sorry for the confusing message.
Try these 2 rules:
RewriteRule ^user/([^/]+)/([^/]+)/?$ index.php?p=user/$1&id=$2 [L,QSA]
RewriteRule ^user/([^/]+)/?$ index.php?p=user/$1 [L,QSA]
Explanation:
Reason why your rule aren't working because your regex is wrong. You first rule ^user/(.*)$ has .* which is matching everything after /user/ hence your 2nd rule never fires and $_GET['id'] is always empty.
By changing that to [^/]+ my rule is matching only until next / is found hence both rules co-exist fine.
QSA is just nice flag to have here to preserve any existing query string.

Categories