Apache-2.4

在 php-fpm 處理它之前將所有 *.php 重寫為單個 index.php (apache)

  • February 2, 2017

通過將所有遺留 PHP 文件請求傳遞給 .htaccess 文件中的 index.php,遺留應用程序通過 Slim 框架傳遞。此外,Symfony 應用程序設置在一個設置了別名的文件夾中。

使用 PHP-FPM 的 VHost 配置

<VirtualHost *:80>
   ServerName example.com
   DocumentRoot /path/to/app/slim
   Alias /system /path/to/app/symfony
   <IfModule mpm_itk_module>
           AssignUserId web_user web_user
   </IfModule>
   <LocationMatch "^(.*\.php)$">
           ProxyPass fcgi://127.0.0.1:9001/path/to/app/slim
   </LocationMatch>
</VirtualHost>

測試文件:

/path/to/slim/index.php

<?php echo "slim";

/path/to/slim/.htaccess

RewriteEngine On
RewriteBase /    
RewriteRule ^hello$ /hello.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

/path/to/slim/hello.php:

<?php echo "hello";

/path/to/symfony/app.php

<?php echo "symfony";

/path/to/symfony/.htaccess:

DirectoryIndex app.php
<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
   RewriteRule ^(.*) - [E=BASE:%1]
   RewriteCond %{HTTP:Authorization} .
   RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

   RewriteCond %{ENV:REDIRECT_STATUS} ^$
   RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]

   RewriteCond %{REQUEST_FILENAME} -f
   RewriteRule ^ - [L]

   RewriteRule ^ %{ENV:BASE}/app.php [L]
</IfModule>


Test Uri                 Expected Output           Actual Output

/hello.php               hello                     hello
----------------------------------------------------------------------
/test                    slim                      slim
----------------------------------------------------------------------
/test.php                slim                      404 error
                                                  [proxy_fcgi:error] [pid 18527] [client x.x.x.x:45357] AH01071: Got error 'Primary script unknown\n'
----------------------------------------------------------------------
/system/hello            symfony                   symfony
/system/app.php/hello    symfony                   symfony

我在 Ubuntu 16 和 CentOs 7 上都試過了,結果相同。使用 Apache 2.4,啟用 AllowOverride All 和 mod_rewrite。PHP7-fpm

我還嘗試了什麼:

  1. ProxyPass fcgi://127.0.0.1:9001/path/to/app/slim/index.php

for /test.php 顯示“slim”,但是該請求在 slim 框架中被誤解為“/”。

根據Apache 文件 .htaccess應該首先進行處理。

解決此問題的最佳方法是什麼?

(注意:賞金說我不想標準化 Apache 配置。這是一個錯字。

我確實想標準化 Apache 配置)

您的問題是使用for 代理到 php-fpm,它在檢查是否存在相應文件之前<LocationMatch>應用於所有 URL 。(順便說一句,會更優雅地做同樣的事情。)引用以下文件ProxyPassMatch<Location>

<Location>部分完全在文件系統之外執行。

但是,您顯然確實想在將 PHP 文件傳遞給 php-fpm 之前檢查它是否存在。這可以通過使用<FilesMatch>andSetHandler來完成:

<FilesMatch \.php$>
   SetHandler "proxy:fcgi://127.0.0.1:9001/"
</FilesMatch>

(我自己在這裡使用 unix 套接字,正如我在上面連結到的文件中一樣,所以我不是 100% 確信這是 URL 的正確語法。)

這樣,只有文件將被重定向到 php-fpm,並且當相應的文件不存在時,您的 mod_rewrite 規則甚至有可能應用於以 .php 結尾的 URI。

還要注意 usingFallbackResource對此沒有影響,因為<LocationMatch>php-fpm 再次具有優先級和代理甚至不存在的 URI。它只重定向那些原本會使用 Apache 的內置 404 處理程序的 URI,但正如您已經指出的那樣,它不會啟動。

引用自:https://serverfault.com/questions/828679