Try it like this instead in the root .htaccess
file:
Options -MultiViews
RewriteEngine On
# Redirect to remove ".php" and optional "slug" query string
RewriteCond /%{QUERY_STRING} ^(?:(/)(?:slug=([^/&]+))|/.*)$
RewriteRule ^([^./]+)\.php$ /$1%1%2 [QSD,R=301,END]
# Redirect to remove "slug" query string (when ".php" is not present on URL-path)
RewriteCond %{QUERY_STRING} ^slug=([^/&]+)$
RewriteRule ^([^./]+)$ /$1/%1 [QSD,R=301,END]
# Rewrite to append ".php" extension
# Handles both "/about" (empty "slug") and "/abc/fased"
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^./]+)(?:/([^/]+))?$ $1.php?slug=$2 [END]
In the directives you posted the RewriteBase
directive was superfluous.
This handles both scenarios. ie. Requests for /about
and /abc/fased
. Requests for /about
are internally rewritten with an empty slug
URL parameter. However, this also means that /about/foo
would also be a valid request (and serve /about.php
). But that is really an issue with your "generalised" URL structure not these directives.
The first two rules handle the canonical redirects for SEO (you should already be linking to the canonical URLs internally). For example:
/about.php
redirects to /about
/abc?slug=fased
redirects to /abc/fased
/abc.php?slug=fased
redirects to /abc/fased
However, if any other URL parameters are present on the request then the condition won't match and there will be no redirect.
Clear your browser cache before testing and test first with a 302 (temporary) redirect to avoid potential caching issues.