ugsgknt
ugsgknt

Reputation: 115

.htaccess rewrite URL in PHP usng apache mod_rewrite

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

Answers (1)

Walf
Walf

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

Related Questions