I have these files in my root, Inside pages i have php files for example projects.php, I tried writing in .htaccess rules to take the file for example xxx.com/projects to open the file from /pages/projects.php and it worked with the following
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} . [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# No file extension on request then append .php and rewrite to subdir
RewriteCond %{REQUEST_URI} /(.+)
RewriteRule !.[a-z0-4]{2,4}$ /pages/%1.php [NC,L]
# All remaining requests simply get rewritten to the subdir
RewriteRule (.*) /pages/$1 [L]
My problem here is when i go to the root xxx.com instead of opening index.php its opening pages directory but if i go explicitely to xxx.com/index.php it works.
I dont want index.php to be shown in the url i need to exclude the root from my rule and make it open index.php while the url stays xxx.com
2
Answers
To exclude "the root" being rewritten to
/pages/
(and serveindex.php
from the root instead) you can simply change the quantifier in the last rule from*
(0 or more) to+
(1 or more) – so that it doesn’t match requests for the root (an empty URL-path in.htaccess
).In other words:
Incidentally, you have already done something similar in the preceding rule/condition by using
+
in the CondPattern, ie.RewriteCond %{REQUEST_URI} /(.+)
.I thought about this other solution:
You wanted to hide
index.php
. This can be done with a 404 error.So you could just do:
But you’ll probably want to avoid also someone requesting
/pages
to list all the PHP files or to directly access/pages/your-page.php
. So I used a regex that matches both the directory and PHP file extensions (only lowercase here, but you could use.(?i)php
where(?i)
enables the case insensitive flag).Then, for the rewrite itself, I would capture the URL with
^.*$
which will be available in the$0
backreference which can then be used in the rewrite rule itself and in the rewrite conditions.If the request is not a directory or an existing file then we have to check that the resulting rewritten URL is effectively an existing PHP file in the
pages
directory.I used the
QSA
flag so that you keep the query parameters in the resulting URL. The PHP script can then access them easily via$_GET
. I expect you could also get them by checking some other environment variables if you don’t use this flag. I also had to use theEND
flag which is similar to theL
for Last flag but completely stops the rewrite rules to execute. If you use theL
flag instead the problem is that you’ll get the 404 error due to the fact that/pages/your-page.php
will match the rewrite rule to hide PHP files since the whole process of rewrite rules is run a second time. The rewrite engine loop only stops when the input URL doesn’t get changed anymore by rewrite rules. Yes, this took me ages to understand that rewrite rules are not just run once like they are displayed in the config file!