My .htaccess currently has the following behaviour using the rewrite rules below:
https://example.com/abcd?lol=true
- if file
/abcd.php
exists, openhttps://example.com/abcd.php?lol=true
- if directory and file
/abcd/index.php
exist, openhttps://example.com/abcd/index.php?lol=true
- else open
https://example.com/index.php?lol=true
-> in all three cases the address bar must still show https://example.com/abcd?lol=true
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [END]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ / [END]
Now to my question: I have a new directory /blog/
, where the following must happen:
https://example.com/blog/abcd?lol=true
- open
https://example.com/blog/index.php?lol=true
-> the address bar must still show https://example.com/blog/abcd?lol=true
so I can use php to read the abcd
part, which could be an article name.
How can I append my .htaccess code to achieve this?
CodePudding user response:
Aside: You're not actually doing anything for #2
(ie. "if directory and file /abcd/index.php
exist...") - you are probably relying on default behaviour by mod_dir. However, if you request /abcd?lol=true
and /abcd
exists as a physical directory, there will be a 301 external redirect to append the trailing slash (ie. /abcd/?lol=true
) which will then result in /abcd/index.php
being served. So, this does not strictly show /abcd?lol=true
in the address bar as you suggest. Is that what you are seeing?
To implement the /blog/abcd?lol=true
to /blog/index.php?lol=true
rewrite then replace your last rule with the following:
# Prevent further processing if a file or directory is requested directly
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [END]
# Route requests to blog/index.php
RewriteRule ^blog/. blog/index.php [END]
# Everthing else is routed to "/index.php"
RewriteRule . index.php [END]
This separates out the filesystem checks into their own rule so you aren't doing this twice.
Your previous "last" rule:
RewriteRule ^(.*)$ / [END]
You were only rewriting to /
and then relying on mod_dir issuing an internal subrequest for index.php
(the DirectoryIndex
). You should instead rewrite directly to index.php
as required (no need for the slash prefix). The capturing pattern ^(.*)$
is unnecessary here.