多くの人にとって、Nginx + PHP の構成は、チュートリアルを検索してコピーして貼り付けるだけです。何の問題もないように思えますが、実際には、インターネット上の多くの情報は荒廃しており、抜け穴がたくさんあります。深い理解を求めずにただコピーアンドペーストしていると、遅かれ早かれその代償を払うことになります。
PHP を使用してフロントエンド コントローラー、または端的に言えば統合された入り口を実装するとします。すべての PHP リクエストを同じファイルに送信し、このファイル内の "REQUEST_URI" を解析することでルーティングを実装します。
一般的にはこのように構成されています
現時点では、多くのチュートリアルで次のように Nginx+PHP を構成する方法が説明されています:
server { listen 80; server_name foo.com; root /path; location / { index index.html index.htm index.php; if (!-e $request_filename) { rewrite . /index.php last; } } location ~ /.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /path$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; } }
多くのエラー、または少なくとも悪臭があり、調べればいくつか見つけることができます。
まず、Nginx 設定ファイル内の命令の継承関係を理解する必要があります。
Nginx 設定ファイルは、外側から内側へ、「http」、「server」、「location」などの多くのブロックに分割されています。 .、デフォルト 継承関係は外側から内側へ、つまり内側のブロックは外側のブロックの値をデフォルト値として自動的に取得します。
「index」コマンドから始めましょう
問題の設定では、「location」で定義されています:
location / { index index.html index.htm index.php; }
将来新しい「location」を追加する必要があると、必然的に「」の定義が重複することになります。これは、複数の「場所」が水平関係にあり、継承がないためです。このとき、「index」は「server」に定義する必要があります。継承関係があるため、「index」コマンドは、すべての「場所」で有効になります。
「if」コマンドを見てみましょう
これは最も誤解されているNginxコマンドであると言っても過言ではありません:
if (!-e $request_filename) { rewrite . /index.php last; }
多くの人は一連のチェックを実行するために「if」コマンドを使用することを好みますが、これは実際には "try_files" です "命令の責任:
try_files $uri $uri/ /index.php;
さらに、初心者はよく "if" 命令がカーネルレベルの命令であると考えますが、実際にはその命令の一部ですさらに、Nginx 構成は実際には手続き型ではなく宣言型であるため、非書き換えモジュールからのディレクティブと混合すると、期待どおりの結果が得られない可能性があります。
「fastcgi_params」設定ファイルを見てみましょう
include fastcgi_params;
Nginx には「fastcgi_params」と「fastcgi.conf」という 2 つの fastcgi 設定ファイルがあります。唯一の違いは次のとおりです。後者には、「SCRIPT_FILENAME」の追加の定義行があります:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
注: $document_root と $fastcgi_script_name の間に / はありません。
元々、Nginx には「fastcgi_params」しかありませんでしたが、後に「SCRIPT_FILENAME」を定義する際にハードコーディングを使用していることが判明したため、使用方法を標準化するために「fastcgi.conf」が導入されました。
しかし、これには疑問が生じます。なぜ古い設定ファイルを変更するのではなく、新しい設定ファイルを導入する必要があるのでしょうか?これは、「fastcgi_param」命令が配列型であるためです。通常の命令と同じで、内側の層が外側の層を置き換えます。通常の命令との違いは、同じレベルで複数回使用される場合、代わりに追加されることです。交換されました。つまり、「SCRIPT_FILENAME」が同じレベルで 2 回定義されている場合、両方ともバックエンドに送信されるため、潜在的な問題が発生する可能性があります。このような状況を回避するために、新しい構成ファイルが導入されました。
さらに、セキュリティの問題も考慮する必要があります。PHP が「cgi.fix_pathinfo」をオンにすると、PHP は間違ったファイル タイプを PHP ファイルとして解析する可能性があります。 Nginx と PHP が同じサーバーにインストールされている場合、最も簡単な解決策は、「try_files」コマンドを使用してフィルタリングすることです:
try_files $uri =404;
改良版
前の分析によると、改良版ではありませんオリジナルのバージョンよりもはるかにクリーンです:
server { listen 80; server_name foo.com; root /path; index index.html index.htm index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ /.php$ { try_files $uri =404; include fastcgi.conf; fastcgi_pass 127.0.0.1:9000; } }
上記がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんが Script Home をサポートしてくれることを願っています。