Reputation: 115
In my website, I have 3 kind of urls as shown below,
index.php?p=my-page
index.php?p=my-page&id=12
index.php?p=my-page&id=12&type=d
So, then I need to covert them into
example.com/my-page
example.com/my-page/12
example.com/my-page/12/d
This is how I tried it in my .htaccess
file.
<IfModule mod_rewrite.c>
# (1)
RewriteEngine On
# (2)
Options +FollowSymlinks
Options -MultiViews
# (3)
# Options +SymLinksIfOwnerMatch
# (4)
RewriteBase /
# (5)
# RewriteOptions <options>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.php?p=$1 [L,QSA,NC,B]
# RewriteRule ^([^/]+)/([^/]+)/?$ index.php?p=$1&id=$2 [L,QSA,NC,B]
# RewriteRule ^([^/]+)/([0-9]+)/?$ index.php?p=$1&id=$2 [L,QSA,NC]
</IfModule>
Above first RewriteRule
is working for example.com/my-page
. But second or third is not working for my other 2 urls.
My <a>
tag is looks this:
<a href="/my-page">Page</a> // this is working for me using above first rule
<a href="/my-page/12/">Page</a>
<a href="/my-page/12/d">Page</a>
Can anyone tell me why my rule 2 or 3 does not work in this regard?
Upvotes: 0
Views: 1115
Reputation: 9278
You're using the L
flag on your rules, so once your rule matches, Apache restarts its checks for matches on the substitution. You're also missing the DPI
flag, so that substitution is not just index.php?...
because the PATH_INFO
is appended. What people typically want instead of L
is END
.
You could also condense them into a single rule so you don't have to repeat the RewriteCond
directives for each one:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]++)(?:/([1-9]\d*+)(?:/([^/]++))?+)?+/?+$ index.php?p=$1&id=$2&type=$3 [END,QSA,NC,B]
See the unit tests section of the regex explanation.
In your PHP, ensure parameters are not the empty string, e.g.:
$id = $_GET['id'] ?? '';
if ($id !== '') {
...
}
Upvotes: 1