Home > OS >  Remove query string parameter to create a more user-friendly URL
Remove query string parameter to create a more user-friendly URL

Time:04-01

I have this .htaccess file and I have no knowledge with mod_rewrite,

RewriteEngine On
RewriteRule ^(. [^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{THE_REQUEST} \s/([^.] )\.php [NC]
RewriteRule ^ /%1 [NE,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /$1.php  [L]

What I want to achieve is to have localhost/viewticket/${id} instead of localhost/viewticket.php?id=123

I have tried many .htaccess rules but none worked except this one that hides .php in my URL.

CodePudding user response:

You can use the following code:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/] )/$ $1.php
RewriteRule ^([^/] )/([^/] )/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L

And if it won't works you can read this PDF file: How to remove PHP or HTML extensions with htaccess

CodePudding user response:

I created this one for you, just erase yours and copy this one enjoy^^

IndexIgnore */*

Options FollowSymLinks
AddDefaultCharset utf-8

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^viewticket/([^/] )/?([^/]*)/?([^/]*)$ viewticket.php?id=$1&param2=$2&param3=$3 [L]
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteRule ^(.*)/?$ /$1.php  [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule . index.php [L]
</IfModule>```

CodePudding user response:

Make sure you've changed your internal URLs so you are linking to /viewticket/<id>. Then add the following at the top of the root .htaccess file:

# Prevent MutliViews rewriting "viewticket" and omitting the URL parameter
Options -MultiViews

RewriteEngine On

# Redirect any direct requests to "/viewticket.php?id=<id>" to "/viewticket/<id>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^id=(\d*)
RewriteRule ^(viewticket)\.php$ /$1/%1 [R=301,L]

# Rewrite "/viewticket/<id>" to "viewticket.php?id=<id>"
RewriteRule ^(viewticket)/(\d*)$ $1.php?id=$2 [QSA,L]

If you are not expecting any query string on your "pretty" /viewticket/<id> URL then remove the QSA (Query String Append) flag in the last rule.

$1 is a backreference to the first capturing group (parenthesised subpattern) in the RewriteRule pattern. Likewise, %1 is a backreference to the first capturing group in the last matched CondPattern (RewriteCond directive).

Always test first with 302 (temporary) redirects to avoid potential caching issues and only change to a 301 (permanent) redirect when you are sure everything is working as intended. Clear your browser cache before testing.

Reference:


Additional:

RewriteEngine On
RewriteRule ^(. [^/])/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{THE_REQUEST} \s/([^.] )\.php [NC]
RewriteRule ^ /%1 [NE,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /$1.php  [L]

Your existing directives (that remove the trailing slash and .php extension) are not quite correct.

Your first rule that unconditionally removes the trailing slash will also "try" to remove the trailing slash from directories as well - which will conflict with mod_dir and result in a redirect loop. The negated character class [^/] (to match a non-slash character) in the middle of the regex would seem to be superfluous. This also redirects to HTTP (not HTTPS)?

The second rule that removes the .php extension would also erroneosuly match .php should it appear in the query string portion of the URL. eg. /foo?bar.php would be redirected to /foo?bar. Although the regex ([^.] ) does avoid the perhaps more common case of /foo.php?bar.php being erroneously redirected.

The third rule that appends the .php extension via an internal rewrite could potentially result in a rewrite-loop (500 Internal Server Error) if you received a request of the form /foo/bar and /foo.php exists in the root of the filesystem. Also, the (optional) trailing slash is also captured by the capturing subgroup, since the * quantifier is greedy. This would also result in a malformed rewrite, if it wasn't for the first rule that removes the trailing slash. (But since the trailing slash is removed then the optional trailing slash in this rule is redundant.)

If you still need these rules to remove the trailing slash and handle extensionless .php URLs then have these rules as follows. Make sure you are already linking to the extensionless URLs internally. These rules should follow the rule block I posted above.

# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(. )/$ http://%{HTTP_HOST}/$1 [R=301,L]

# Remove ".php" extension if present on the initial request
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (. )\.php$ /$1 [R=301,L]

# Append ".php" extension if request maps to a PHP file
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.*?)/?$ $1.php  [L]

These directives (and your original directives for that matter) do assume the .htaccess file is located in the document root directory.

  • Related