0

状況

こんにちは、拡張子のない PHP ファイルに関する PHP の期待/デフォルトの動作、および/またはリクエストを処理する (したい) 実際のファイルを「通過する」URL リクエスト (つまり、PHP のデフォルトの「フォールバック」アクションの前) について混乱しています。完全に 404-ing に頼っています)。これが私の状況です:

ローカル サーバー (非常に基本的な PHP 5.5.1 セットアップで nginx 1.5.3 を実行) のディレクトリ構造は次のようになります。

/index
/index.php
/other
/other.php
/rootdir/index
/rootdir/index.php
/rootdir/other
/rootdir/other.php

8 つのファイルすべての内容は同じです。

<?php
echo $_SERVER['PHP_SELF'] . ', ' . $_SERVER['REQUEST_URI'];
?>

しかし、それぞれのエンドポイントに到達すると、(私にとっては) 奇妙な結果が得られます。

リサーチ

GET /index.php
'/index.php, /index.php' # Makes sense...

GET /index.php/something_else
'/index.php, /index.php/something_else' # Also makes sense...

GET /index/something_else
'/index.php, /index/something_else' # Let's call this ANOMALY 1... (see below)

GET /something_else
'/index.php, /something_else' # ANOMALY 2

GET /other.php
'/other.php, /other.php' # Expected...

GET /other.php/something_else
'/index.php, /other.php/something_else' # ANOMALY 3

GET /rootdir/index.php
'/rootdir/index.php, /rootdir/index.php' # Expected...

GET /rootdir/index.php/something_else
'/index.php, /rootdir/index.php/something_else' # ANOMALY 4

GET /rootdir/other.php
'/rootdir/other.php, /rootdir/other.php' # Expected...

GET /rootdir/other.php/something_else
'/index.php, /rootdir/other.php/something_else' # ANOMALY 5

私の理解では、サーバーは/index.php、ユーザーが要求 URI で探しているものを見つけることができない場合にリダイレクトします。それは理にかなっています...私が理解していないのは次のとおりです。

  1. 専用の 404 ページをセットアップしていないにもかかわらず、なぜこれを実行するのか ( /index.php404 する前に試すように指示しませんでした。何かが見つからない場合は、合法的で非カスタムの 404 ページを表示する必要があります。または処理できません. 何かが見つからなかった場合、デフォルトのサーバー 404 ページを表示する必要があると考えました.明らかに常にそうであるとは限りません...?)
  2. /rootdir/index.phpサブディレクトリ内に何かが見つからない場合に試行しないのはなぜですか/rootdir/

質問

  1. 見つからないアドレスに関して、誰かがPHPのロジックが何であるかを明らかにすることができますか(または、nginxが行っているのかもしれません;私はまだそれを理解できていません)? なぜ私は自分が見ているものを見ているのですか? (具体的には、異常 #4 と #5 に関して。/rootdir/index.php「404」の処理に使用することを期待していた、実際の 404 ページを期待していました。フォールバック/index.phpは予想外でした。)

  2. 直接的な帰結 (因果関係?) の質問として、"下" で発生するヒットを処理する拡張機能のない PHP ファイルをシミュレートするにはどうすればよいですか(たとえば、異常 #1 の場合。 、 mod_rewriting 、またはリダイレクトに依存せずに?.htaccessそれともばかげた質問ですか?:-)

参考文献

Apache に依存せずに/some_dir/index.php/fake_subdirand (つまり、異なる「フォールバック ハンドラー」)のようなリクエストを処理するためのカスタム実装を展開しようとしていますが、PHP (または nginx?) のデフォルトのフォールバック動作の背後にあるロジックがわかりません。/some_other_dir/index.php/fake_subdirこれらのページは、主にこの質問が由来する場所です。

4

2 に答える 2

1
 GET /other.php/something_else

これはPATH_INFOApache で呼び出されます。Apache が URL の「ディレクトリ」をスキャンすると、実際にはファイル/スクリプトである最初のファイルが返されます (または最初のスクリプトが実行されます)。

GET /foo/bar/baz/index.php/a/b/c/
     ^--dir
         ^--dir
             ^---dir
                 ^---script
                         ^^^^^^^--- path_info

本当の意味での本当の要求は

GET /foo/bar/baz/index.php

次に、Apache は URL のディレクトリ構造の未使用の末尾部分を取得し、それをパス情報に変換します。PHP では、次のようになります。

$_SERVER['REQUEST_URI'] = '/foo/bar/baz/index.php';
$_SERVER['PATH_INFO'] = 'a/b/c';
于 2013-09-20T16:09:46.217 に答える
0

さて、私は何が起こっているのかを理解しました.nginxサーバーの設定が間違っていました.

Marc B の回答は、Apache に関連しています、PATH_INFO の値を確認するように促されましたGET /other.php/something_else

さらに検索すると、答えが見つかりました。nginx を使用しfastcgi_split_path_infoて URI を a) スクリプトへのパスと b) スクリプト名に続くパスに分割すると、ディスク上のファイルを指すようにURI を書き換えるため、ディレクティブの使用に実行すると失敗します。 . これにより、PATH_INFO 文字列を取得する可能性がなくなります。try_files

解決策として、次の 3 つのことを行いました (これらのいくつかはおそらく冗長ですが、念のためすべてを行いました)。

  1. サーバーのロケーション ブロックでは、PATH_INFO を設定するfastcgi_split_path_info 前に使用します。

    fastcgi_param PATH_INFO $fastcgi_path_info;
    

    ...そして、を利用する前に両方 を行ってください。try_files

  2. 後で$fastcgi_path_info変更された場合に備えて、ローカル変数として保存します (例: set $path_info $fastcgi_path_info;)

  3. を使用する場合は、使用しないtry_filesでください...使用してください。(確かにこれは私の最大の間違いでした。)$uri$fastcgi_script_name

サンプル構成

server {

    # ... *snip* ...

    location ~ \.php {
        # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        fastcgi_split_path_info ^(.+\.php)(/.*)$;

        include fastcgi_params;

        fastcgi_index index.php;
        fastcgi_intercept_errors on;
        fastcgi_pass 127.0.0.1:9000;

        try_files $fastcgi_script_name =404;
    }

    # ... *snip* ...

}

含まれる場所fastcgi_params:

set            $path_info         $fastcgi_path_info;
fastcgi_param  PATH_INFO          $path_info;
fastcgi_param  PATH_TRANSLATED    $document_root$path_info;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

# ... *snip* ...

参照

次のリンクは問題をよく説明しており、別の nginx 構成を提供しています。

于 2013-09-20T21:59:03.310 に答える