web-dev-qa-db-ja.com

php-fpmが処理する前に、すべての* .phpを単一のindex.phpに書き換えます(Apache)

レガシーアプリケーションは、すべてのレガシーPHPファイルリクエストを.htaccessファイルのindex.phpに渡すことにより、スリムフレームワークを通過します。さらに、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

Ubuntu16とCentOs7の両方でこれを試しましたが、同じ結果になりました。 Apache 2.4を使用して、AllowOverrideAllとmod_rewriteを有効にします。 PHP7-fpm

他に何を試しましたか:

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

/test.phpの場合は「スリム」と表示されますが、スリムフレームワークではリクエストが「/」と誤って解釈されます。

Apacheドキュメント によると.htaccessを最初に処理する必要があります。

これを解決するための最良の方法は何ですか?

(注:Bountyは、Apache構成を標準化したくないと言っています。これはタイプミスです。

Apache構成を標準化したい)

2
jdog

あなたの問題は、php-fpmにプロキシするために<LocationMatch>を使用することです。これは、対応するファイルが存在するかどうかをチェックする前にすべてのURLに適用されます。 (ちなみに、ProxyPassMatchは同じことをよりエレガントに行います。)引用するには <Location>のドキュメント

<Location>セクションは完全にファイルシステムの外部で動作します。

ただし、明らかにdoは、php-fpmに渡す前にPHPファイルが存在するかどうかを確認する必要があります。代わりに<FilesMatch>および SetHandler を使用して実行します。

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

(私自身、上記でリンクしたドキュメントのように、ここでunixソケットを使用しているので、これがURLの正しい構文であると100%確信しているわけではありません。)

このように、filesのみがphp-fpmにリダイレクトされ、mod_rewriteルールは.phpで終わるURIにも適用される可能性があります。対応するファイルが存在しません。

FallbackResourceを使用しても、これには影響がないことにも注意してください。これも、<LocationMatch>が優先され、存在しないURIでもphp-fpmにプロキシされるためです。それ以外の場合はApacheの組み込み404ハンドラーを使用するURIのみをリダイレクトしますが、すでに述べたようにそれは機能しません。

1
jplitza

一見すると、仮想ホストにAllowOverrideディレクティブがないように見えるので、ファイルが読み取られていないのは正常ですが、それでも疑問に思います。

仮想ホストにアクセスできるのに、なぜ.htaccessを使用しているのですか?あなたはそれを使って(あなたがすでにやっているように見えるように)あなたの人生を複雑にしようとしているだけです。

.htaccessとそれらすべての書き換えディレクティブを忘れて、仮想ホストに次の単純な行を追加します。

FallBackResource /index.php

これは基本的に、5つの書き換えディレクティブすべてが行うのと同じことを1行で実行します。

"プライマリスクリプト不明"について、fpmの内容を確認してください。間違ったパスとfpmの設定が間違っている

悪夢や絶え間ない頭痛を避けるために、可能な限り、ディレクトリごとのコンテキストでディレクティブを定義しないようにしてください。

0
ezra-s

_/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ディレクティブの前に直接配置します。

0
cnst