検索
ホームページバックエンド開発PHPチュートリアル怎么正确配置Nginx+PHP及正确的nginx URL重写

如何正确配置Nginx+PHP及正确的nginx URL重写

对很多人而言,配置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」等等,缺省的继承关系是从外到内,也就是说内层块会自动获取外层块的值作为缺省值(有例外,详见参考)。

参考:UNDERSTANDING THE NGINX CONFIGURATION INHERITANCE MODEL

让我们先从「index」指令入手吧,在问题配置中它是在「location」中定义的:

location / {    index index.html index.htm index.php;}

一旦未来需要加入新的「location」,必然会出现重复定义的「index」指令,这是因为多个「location」是平级的关系,不存在继承,此时应该在「server」里定义「index」,借助继承关系,「index」指令在所有的「location」中都能生效。

参考:Nginx Pitfalls

接下来看看「if」指令,说它是大家误解最深的Nginx指令毫不为过:

if (!-e $request_filename) {    rewrite . /index.php last;}

很多人喜欢用「if」指令做一系列的检查,不过这实际上是「try_files」指令的职责:

try_files $uri $uri/ /index.php;

除此以外,初学者往往会认为「if」指令是内核级的指令,但是实际上它是rewrite模块的一部分,加上Nginx配置实际上是声明式的,而非过程式的,所以当其和非rewrite模块的指令混用时,结果可能会非你所愿。

参考:IfIsEvil and How nginx “location if” works

下面看看「fastcgi_params」配置文件:

include fastcgi_params;

Nginx有两份fastcgi配置文件,分别是「fastcgi_params」和「fastcgi.conf」,它们没有太大的差异,唯一的区别是后者比前者多了一行「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」,那么它们都会被发送到后端,这可能会导致一些潜在的问题,为了避免此类情况,便引入了一个新的配置文件。

参考:FASTCGI_PARAMS VERSUS FASTCGI.CONF – NGINX CONFIG HISTORY

此外,我们还需要考虑一个安全问题:在PHP开启「cgi.fix_pathinfo」的情况下,PHP可能会把错误的文件类型当作PHP文件来解析。如果Nginx和PHP安装在同一台服务器上的话,那么最简单的解决方法是用「try_files」指令做一次过滤:

try_files $uri =404;

参考:Nginx文件类型错误解析漏洞

依照前面的分析,给出一份改良后的版本,是不是比开始的版本清爽了很多:

server {    listen 80;    server_name foo.com;    root /path;    index index.html index.htm index.php;    location / {<pre style="margin-top:0px; margin-bottom:1.625em; background-color:rgb(244,244,244); border:0px; font-family:'Courier 10 Pitch',Courier,monospace; font-size:13px; outline:0px; padding:0.75em 1.625em; vertical-align:baseline; line-height:1.5; overflow:auto; color:rgb(55,55,55)"><span style="white-space:pre"></span><pre style="margin-top:0px; margin-bottom:1.625em; background-color:rgb(244,244,244); border:0px; font-family:'Courier 10 Pitch',Courier,monospace; font-size:13px; outline:0px; padding:0.75em 1.625em; vertical-align:baseline; line-height:1.5; overflow:auto; color:rgb(55,55,55)">#  此处注释部分URL重写的正确写法 修改为下面 那一行替代#  if (!-e $request_filename) {#      rewrite . /index.php last;#  }<span style="background-color:rgb(240,240,240); line-height:1.5">try_files $uri $uri/ /index.php$is_args$args;#这里后面的 $is_args$args是为了获取URL参数的,不获取可省略</span>
}
 location ~ \.php$ {                                  try_files $uri =404;#这里加入这一行,防止出错的 页面被PHP解析                                  include fastcgi.conf;                                  fastcgi_pass 127.0.0.1:9000;        <span style="background-color:rgb(240,240,240); line-height:1.5">     }</span><span style="background-color:rgb(240,240,240); line-height:1.5">}</span>

实际上还有一些瑕疵,主要是「try_files」和「fastcgi_split_path_info」不够兼容,虽然能够解决,但方案比较丑陋,具体就不多说了,有兴趣的可以参考问题描述。

补充:因为「location」已经做了限定,所以「fastcgi_index」其实也没有必要。

希望大家以后不要再拷贝粘贴了,如果实在改不了,那么就请拷贝粘贴本文。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPでarray_randでキーをランダムに取得するにはどうすればよいですか?PHPでarray_randでキーをランダムに取得するにはどうすればよいですか?May 15, 2025 pm 08:36 PM

PHPでは、array_rand関数を使用して、配列からランダムにキーを取得できます。 1)array_rand($ array)を使用して、単一のランダムキーを取得します。 2)array_rand($ array、n)を使用して、nランダムキーを取得します。この機能は効率的で柔軟ですが、大規模なデータの主要なカウントとパフォーマンスの問題の制限に注意を払う必要があります。

PHPで機能のホットアップデートを実装する方法は?PHPで機能のホットアップデートを実装する方法は?May 15, 2025 pm 08:33 PM

PHPに機能のホットアップデートを実装するには、次の3つの方法があります。 2。opcacheを使用して、opcacheを再起動してホットアップデートを実現します。 3.展開やAnsibleなどの外部ツールを使用して、コードを自動的に展開および更新します。

PHPアレイを反復しながら要素を交換する方法は?PHPアレイを反復しながら要素を交換する方法は?May 15, 2025 pm 08:30 PM

PHPでは、次の方法を使用して配列要素を横断および交換できます。1。foreachループと参照(&$値)を使用して要素を変更しますが、参照が副作用を引き起こす可能性があることに注意してください。 2。forループを使用して、インデックスと値に直接アクセスして、参照の問題を回避します。 3. array_map関数を使用して簡潔な変更を加えますが、キー名はリセットされます。 4. array_walk関数を使用して値を変更し、キー名を保持します。方法を選択する際には、パフォーマンス、副作用、キー名保持要件を考慮する必要があります。

PHPでISBN文字列を検証する方法は?PHPでISBN文字列を検証する方法は?May 15, 2025 pm 08:27 PM

PHPのISBN文字列の検証は、ISBN-10とISBN-13の2つの形式を処理できる関数を介して実装できます。 1.すべての非数字を削除します。 2。ISBN-10の場合、加重和の計算が使用され、結果を11。3で割ることができる場合は有効です。ISBN-13の場合、異なる重み付け和の計算を使用し、結果を10で割ることができる場合は有効です。

PHPでクラスの自動負荷を実装する方法は?PHPでクラスの自動負荷を実装する方法は?May 15, 2025 pm 08:24 PM

PHPでは、__ autoloadまたはspl_autoload_register関数を介してクラスを自動的にロードすることが実装されます。 1. __ autoload関数は放棄されました。2。spl_autoload_register関数はより柔軟で、複数の自動荷重機能をサポートし、名前空間とパフォーマンスの最適化を処理できます。

PHPで配列要素を変更する方法は?PHPで配列要素を変更する方法は?May 15, 2025 pm 08:21 PM

PHPの配列要素を変更する方法には、関数を使用した直接割り当てとバッチ変更が含まれます。 1。$ colors = ['red'、 'green'、 'blue'などのインデックス付き配列の場合、2番目の要素は$ colors [1] = 'Yellow'で変更できます。 2。$ person = ['name' =&gt; 'john'、 'age' =&gt; 30]などの連想配列の場合、年齢の価値は$ person ['age'] = 31で変更できます。 3. array_mapまたはarray_walk関数を使用して、$ numbers = array_mapなどのバッチの配列要素を変更する

PHPにフック機能を実装する方法は?PHPにフック機能を実装する方法は?May 15, 2025 pm 08:18 PM

PHPでフック関数の実装は、オブザーバーモードまたはイベント駆動型プログラミングを介して実装できます。特定の手順は次のとおりです。1。フックを登録およびトリガーするフックマネージャークラスを作成します。 2。レジスタホックメソッドを使用してフックを登録し、必要に応じてトリガーフックメソッドでフックをトリガーします。フック関数は、コードのスケーラビリティと柔軟性を向上させることができますが、パフォーマンスのオーバーヘッドとデバッグの複雑さに注意を払ってください。

トラフィックの高いウェブサイトのPHPパフォーマンスチューニングトラフィックの高いウェブサイトのPHPパフォーマンスチューニングMay 14, 2025 am 12:13 AM

thesecrettokeepingaphp-poweredwebsterunningsmootlyunderheavyloadinvolvesseveralkeystrategies:1)emform opcodecoduceSciptionexecutiontime、2)aatabasequerycachingwithiThing withiThistolessendavasoload、

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境