mod_rewrite, php and the .htaccess file
One approach is to rewrite everything to a handling script
RewriteEngine on
RewriteBase /
# only rewrite if the requested file doesn't exist
RewriteCond %{REQUEST_FILENAME} !-s
# pass the rest of the request into index.php to handle
RewriteRule ^(.*)$ /index.php/$1 [L]
so if you have a request to http://yourserver/foo/bar/
what you actually get is a request to http://yourserver/index.php/foo/bar - and you can leave index.php to decide what to do with /foo/bar (using $_SERVER['PATH_INFO'] -tom)
You only need to modify .htaccess the first time. All future requests for inexistent files can then be handled in PHP.
You might also find the docs for mod_rewrite useful - but keep it simple or prepare to lose a lot of sleep and hair tracking down obscure errors.
mod_rewrite interaction between two .htaccess files
As already been mentioned in comments/answer that Apache .htaccess is per-directory directive. Apache only uses closest/nearest .htaccess so in your case it is only using /product/blog/.htaccess
and ignoring /.htaccess
:
You can use this directive at top of your /product/blog/.htaccess
:
RewriteOptions InheritBefore
This will make rules from the parent scope are applied before rules specified in the child scope.
Here is Apache documentation
.htaccess, use mod_rewrite to rewrite to a file OUTSIDE the web root
Short answer: no. The webserver can't directly access files outside of the document root. If you think about it, there would be quite a security problem if it could. What you can do is rewrite to a file within the document root that includes or reads from the file that is located outside of the root. (Moved from comments...)
how to write mod_rewrite rule in .htaccess
If I understand what you need, this will do it:
RewriteEngine On
RewriteRule ^(.*)project/(.*)/(.*).php$ /$2/$3.php [L,R=301]
RewriteRule ^(.*)project/(.*).php$ /$2.php [L,R=301]
RewriteRule ^(.*)project/(.*)test$ /new_test.php [L,R=301]
RewriteRule ^(.*)project/(.*)$ /test.php [L,R=301]
By the way, the order of the rules here is very important, so you have to keep it exactly the same.
mod_rewrite is enabled, .htaccess file is ok, but requests are not going through index.php
You should check if for that specific directory (root folder of your project), apache is configured to allow overriding through .htaccess.
If you want to allow such override, the directives found in apache.conf or the specific settings for your virtual host should look like this:
<Directory /var/www/>
AllowOverride All
Require all granted
</Directory>
How can I use the .htaccess file to rewrite URL's for a subdirectory?
Just to be sure, I should be able to put another
.htaccess
in a subdirectory and expect it to rewrite the urls forexample.com/sub
, right?
Yes. The mod_rewrite directives in the /subdir/.htaccess
file will, by default, completely override the mod_rewrite directives in the parent/root .htaccess
file. However, you will need to redefine the ErrorDocument
directives in order to override the root.
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
To clarify, with these two conditions are you wanting to occasionally serve the index.html
or index.php
(DirectoryIndex) document from a requested subdirectory, instead of routing the request to /index.php
in the document root? In this case it would be more common (and marginally more optimal) to simply check that the request does not map to a directory instead (ie. RewriteCond %{REQUEST_FILENAME} !-d
). Unless there are some physical subdirectories that you want to route to /index.php
in the document root?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>
These directives could be simplified slightly - and this will help you if you want to apply the same directives to the subsite in /subdir
(and serve /subdir/index.php
instead).
Remove the RewriteBase
directive entirely. The relative susbtitution string, ie. index.php
, will then be relative to the directory where the .htaccess
file is located (or inherited).
You also don't need the <IfModule mod_rewrite.c>
wrapper. See my answer to the following question on the Webmasters Stack for more information on this: https://webmasters.stackexchange.com/questions/112600/is-checking-for-mod-write-really-necessary
So, the above can be written:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
(And note my comment above about replacing the two conditions with a directory check instead.)
Now, you could simply copy the exact same directives into the /subdir/.htaccess
file and these will now route requests to /subdir/index.php
instead, overriding the mod_rewrite directives in the parent.
No need to copy Options -Indexes
, unless you want to change this option.
OR, if you want to apply the exact same directives (but in relation to the /subdir
) you could simply enable mod_rewrite inheritance in the /subdir/.htaccess
file. For example:
# /subdir/.htaccess
ErrorDocument 403 /subdir/404.php
ErrorDocument 404 /subdir/404.php
RewriteEngine On
RewriteOptions Inherit
The effect of RewriteOptions Inherit
is to essentially "copy" the mod_rewrite directives from the parent config, ie. /.htaccess
in the root, behind the directives in the current /subdir/.htaccess
file. It is important to clarify that the directives are "copied", they are not run in-place as if in the root /.htaccess
file.
Related Topics
Call to Undefined Function Odbc_Connect() Message While Connecting Sap Hana Database
Convert Exponential Number to Decimal in PHP
How to Pass Parameters into a PHP Script Through a Webpage
Load Blade Assets with Https in Laravel
Memory_Get_Peak_Usage() with "Real Usage"
Print Currency Number Format in PHP
Simple Way to Read Single Record from MySQL
PHP - Check If the Page Run on Mobile or Desktop Browser
Why Is Calling a Function (Such as Strlen, Count etc) on a Referenced Value So Slow
Call to Undefined Method Domdocument::Getelementsbyclassname()
Hunting Cheaters in a Voting Competition
How to Do Model->Where('Id', Array) Multiple Where Conditions