Унаследованное приложение передается через Slim framework путем передачи всех устаревших запросов файлов PHP в index.php в файле .htaccess. Далее, приложение Symfony устанавливается в папке с установленным псевдонимом.
Конфигурация VHost с PHP-FPM
<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 / путь / к / app / slim / index.php
для /test.php отображается «тонкий», однако в этом случае запрос неверно интерпретируется в тонкой структуре как «/».
В соответствии с Документация Apache .htaccess
должны быть обработаны в первую очередь.
Как лучше всего решить эту проблему?
(Примечание: Баунти говорит, что я не хочу стандартизировать конфигурацию Apache. Это опечатка.
Я ХОЧУ стандартизировать конфигурацию Apache)
Ваша проблема в использовании <LocationMatch>
для проксирования на php-fpm, который применяется ко всем URL-адресам перед проверка наличия соответствующего файла. (ProxyPassMatch
кстати, сделал бы то же самое более элегантно.) документация по <Location>
:
<Location>
разделы работают полностью вне файловой системы.
Однако вы, очевидно, делать хотите проверить, существует ли файл PHP, прежде чем передавать его в php-fpm. Это можно сделать, используя <FilesMatch>
и SetHandler
вместо:
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9001/"
</FilesMatch>
(Я сам использую здесь сокеты unix, как и в документации, на которую я ссылался выше, поэтому я не уверен на 100%, что это правильный синтаксис для URL-адреса.)
Только так файлы будет перенаправлен на php-fpm, и ваши правила mod_rewrite могут применяться даже к URI, заканчивающимся на .php, когда соответствующие файлы не существуют.
Также обратите внимание, что использование FallbackResource
не влияет на это, потому что снова <LocationMatch>
имеет приоритет и передает в php-fpm даже несуществующие URI. Он перенаправляет только те URI, которые в противном случае использовали бы встроенный обработчик 404 Apache, но это не срабатывает, как вы уже отметили.
Вы утверждаете, что запросы вроде /test
работа, но /test.php
не надо.
Когда это происходит, всегда ли /test.php
не существует, и это запрос, заканчивающийся на .php
? Если да, то вы могли бы указать браузеру автоматически сделать другой запрос, удалив .php
часть.
Что можно сделать с помощью:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*)\.php$ $1 [R]
Согласно http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule, то R
вариант выдал бы redirect
.
Я бы не поверил .htaccess
, и поместите его прямо в конфигурацию сервера в <LocationMatch "^(.*\.php)$">
который у вас уже есть, и до ProxyPass
директива внутри него.
На первый взгляд кажется, что у вас нет директивы AllowOverride на виртуальном хосте, поэтому нормально, что файл не читается, но мне интересно:
Почему вы используете .htaccess, если у вас есть доступ к виртуальному хосту? Вы просто хотите усложнить себе жизнь (как вы, кажется, уже делаете), используя его.
Забудьте о .htaccess и всех этих директивах перезаписи и добавьте эту простую строку в свой виртуальный хост:
FallBackResource /index.php
По сути, это будет делать то же самое, что и все ваши 5 директив перезаписи, в одной строке.
Около "основной сценарий неизвестен", проверьте, что говорит fpm, возможно, вы указываете на неправильный путь и неверная настройка fpm
Не забывайте по возможности избегать определения ваших директив в контексте каталога, чтобы избежать кошмаров и постоянных головных болей.