.htaccess重写规则对PHP文件失效问题求助
This behavior happens because Apache's PHP processing module (either mod_php or PHP-FPM paired with Apache) intercepts .php requests before mod_rewrite gets a chance to run in specific scenarios. Here's a breakdown of what's going on and how to fix it:
What's Causing the Issue?
When you request a .php file that doesn't exist in the root directory, Apache's PHP handler checks for the physical file first. If it can't find it, it immediately returns a 404 error without passing the request through your rewrite rules. For non-PHP files and directories, this doesn't happen because no specialized module is intercepting the request early.
When the root directory does have the .php file, mod_rewrite runs first (since the file exists, Apache doesn't trigger the early 404) and redirects the request to the Web subdirectory—hence why you see the Web version even though the root file exists.
Fix 1: Disable MultiViews First
First, add -MultiViews to your Options directive. MultiViews (part of mod_negotiation) automatically tries to match file extensions, which can interfere with rewrite rules for PHP files:
Options -MultiViews +FollowSymLinks RewriteEngine On RewriteBase / # Exclude requests already targeting the Web directory RewriteCond %{REQUEST_URI} !^/Web/ # Force all requests to the Web subdirectory RewriteRule ^(.*)$ /Web/$1 [QSA,L]
Fix 2: Force Rewrite for All PHP Requests (If Fix 1 Doesn't Work)
If the first fix doesn't resolve the issue, you need to temporarily disable PHP's handler for the root directory so mod_rewrite can process the request before PHP takes over. Add these directives to your .htaccess:
Options -MultiViews +FollowSymLinks RewriteEngine On RewriteBase / # Disable PHP handler for root directory to let rewrite rules run first <FilesMatch "\.php$"> SetHandler None </FilesMatch> # Rewrite all non-Web requests to the Web subdirectory RewriteCond %{REQUEST_URI} !^/Web/ RewriteRule ^(.*)$ /Web/$1 [QSA,L] # Re-enable PHP handler for the Web subdirectory <Directory "/Web"> <FilesMatch "\.php$"> # Replace with your PHP handler (adjust if using PHP-FPM) SetHandler application/x-httpd-php </FilesMatch> </Directory>
Note: This requires AllowOverride All in your Apache server config for the root directory, since it uses <Directory> and <FilesMatch> directives.
Why This Works
- Disabling
MultiViewsprevents Apache from guessing file extensions and skipping rewrite rules. - Temporarily disabling the PHP handler for the root ensures
mod_rewritecan redirect the request to theWebsubdirectory before PHP tries to process the non-existent root file.
内容的提问来源于stack exchange,提问作者Chris

