Перепишите все * .php в один index.php до того, как php-fpm обработает его (apache)

Унаследованное приложение передается через 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";

/ путь / к / 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 / путь / к / приложению / slim / index.php

для /test.php показывает "тонкий", однако запрос затем неверно интерпретируется в тонкой структуре как "/".

. Согласно документации Apache .htaccess должен быть обработан первым.

Как лучше всего решить эту проблему?

(Примечание: Баунти говорит, что я не хочу стандартизировать конфигурацию Apache. Это опечатка.

Я ХОЧУ стандартизировать конфигурацию Apache)

2
задан 28 January 2017 в 09:16
3 ответа

Ваша проблема заключается в использовании для проксирования в php-fpm, который применяется ко всем URL-адресам перед проверкой наличия соответствующего файла существует. ( ProxyPassMatch , кстати, сделает то же самое более элегантно.) Процитируем документацию по :

разделы работают полностью вне файловой системы.

Однако вы, очевидно, действительно хотите проверить, существует ли файл PHP, прежде чем передавать его в php-fpm. Это можно сделать, используя вместо этого и SetHandler :

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

(Я сам использую здесь сокеты unix, как и в документации, на которую я ссылался выше, поэтому я не на 100% уверен, что это правильный синтаксис для URL.)

Таким образом, только файлы будут перенаправлены на php-fpm, и ваши правила mod_rewrite могут быть применены даже к URI, заканчивающимся в .php, когда соответствующие файлы не существуют.

Обратите внимание, что использование FallbackResource не влияет на это, потому что снова имеет приоритет, а прокси даже не существуют URI для php-fpm. Он перенаправляет только те URI, которые в противном случае использовали бы встроенный обработчик 404 Apache, но это не срабатывает, как вы уже отметили.

2
ответ дан 3 December 2019 в 11:30

На первый взгляд кажется, что у вас нет директивы AllowOverride на виртуальном хосте, поэтому нормально, что файл не читается, но мне интересно:

Почему вы используете .htaccess если у вас есть доступ к виртуальному хосту? Вы просто хотите усложнить себе жизнь (как вы, кажется, уже делаете), используя его.

Забудьте о .htaccess и всех этих директивах перезаписи и добавьте эту простую строку в свой виртуальный хост:

FallBackResource /index.php

По сути, это будет то же самое то, что делают все ваши 5 директив перезаписи, в одной строке.

По поводу " primary script unknown ", проверьте, что должен сказать fpm, вы можете указать неверный путь и настроить fpm неправильно

Не забывайте по возможности избегать определения ваших директив в контексте per-dir, чтобы избежать кошмаров и постоянной головной боли.

0
ответ дан 3 December 2019 в 11:30

Вы утверждаете, что запросы типа / 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 вызовет перенаправление .

Я бы не стал доверять .htaccess , и поместите его непосредственно в конфигурацию сервера в пределах , который у вас уже есть, но до Директива ProxyPass внутри него.

0
ответ дан 3 December 2019 в 11:30

Теги

Похожие вопросы