I have simple php application with navigation based on domain/foo/bar
nested urls.
For instance, I have main page index.php
with about
nav link which should navigate to domain/en/about
, where en
and about
must be transfered to url param like index.php?url=...
.
But when I click to about
I got to domain/en/about
and
404 not found instead.
I have configured apache2 virtual domain config as:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
<Directory /var/www/html/domain>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
DocumentRoot /var/www/domain/
ServerName domain.local
ServerAlias www.domain.local
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
And .htaccess
file as:
order deny,allow
RewriteEngine On
RewriteBase /
RewriteRule .* index.php?url=$0 [QSA,L]
mod_rewrite
for apache2 is already enabled.
Have no clue what I have missed.
Any help is appreciated!
Thank you in advance!
2
Answers
You need parenthesis around what you want to capture. Back-references indices start with ‘1’:
Your
<Directory>
section andDocumentRoot
directive refer to different locations, so regardless of where you’ve put the.htaccess
file, it’s not going to work as intended.However…
This rule is not strictly correct, since it ends up rewriting itself on a second pass by the rewrite engine. If it wasn’t for the
QSA
flag, the originalurl
param value (that contains the originally requested URL-path) would be lost. The above ends up rewriting a request for/en/about
toindex.php?url=index.php&url=en/about
. Fortunately, your PHP script still reads$_GET['url']
asen/about
. But you can examine the full (erroneous) query string in$_SERVER['QUERY_STRING']
.(And, if you were to simply prefix the substitution string with a slash, ie. a URL-path, you’ll get an endless rewrite-loop (500 Internal Server Error). But this could also result from adding additional rules later.)
You should prevent requests to
index.php
itself being rewritten, which you can do by adding an additional rule. For example:However, this will still rewrite your static assets (assuming you are linking to internal images, CSS and JS files?). So, you would normally need to prevent this with an additional condition that prevents the rule from being processed if the request already maps to a static file.
For example:
The CondPattern
-f
checks if the TestString maps to a file. The!
prefix negates this. So the condition is only successful when the request does not map to a file.