phpチュートリアルにはシーケンスの詳細な説明が必要/含まれています
大規模な Web プロジェクトでは、include_path はモジュラー設計の基礎です (もちろん、自動ロードに基づいた設計も数多くありますが、これはこの記事の議論に影響しません)。しかし、それはまさに include_path のせいで、しばしば遭遇するものです。正しいファイルが見つからないことによって引き起こされる「奇妙な」問題は、次のような疑問にもつながります。 include_path が複数ある場合、どのような順序で機能するのでしょうか? 今日は、以下のディレクトリ構造の例から始まるこの問題の包括的な説明: root 1.php 3.php subdir 2.php 1.php 内の 3.php:
コードをコピーします コードは次のとおりです:
ini_set("include_path", ".:path_to_subdir");
require("2.php");
?>そして 2.php:
コードをコピーします コードは次のとおりです:
require("3.php");
?> そして、ルートディレクトリの 3.php は「root」を出力し、サブディレクトリの 3.php は「subdir」を出力します。
1. ルート ディレクトリで 1.php を実行すると、どのような出力が得られますか?
2. サブディレクトリの下の上位ディレクトリで 1.php を実行すると、どのような出力が得られますか?
3. include_path の現在のディレクトリ パスをキャンセルする場合 (つまり、include_path="path_to_subdir")、上記 2 つの質問の出力はどうなりますか?
PHP の include_path
PHP は require(_once)/include(_once) 命令に遭遇すると、まず次の判断を行います:
コードをコピーします コードは次のとおりです:
含めるファイルパスは絶対パスですか?
その場合は、直接含めて終了します。
そうでない場合は、別のロジックを入力して (複数の呼び出しの後、マクロ展開後に _php_stream_fopen_with_path を入力します)、このファイルを見つけます。 次に、_php_stream_fopen_with_path で、次の判定が行われます。
コードをコピーします コードは次のとおりです:
含めるファイル パスは相対パス (./file、../dir/file の形式、以下では「ディレクトリ相対パス」に置き換えます) ですか?
その場合は、include_path のロジックをスキップして、相対パス (後で別途説明します) を直接解析します。たとえば、次の例では、選択されるディレクトリのリストが、include_path と現在実行されているファイルのパスに基づいて作成されます。前回の記事では、以下の待機リストが作成されます
。
コードをコピーします コードは次のとおりです:
".:path_to_subdir:current_script_dir 次に、候補リストの先頭から、default_dir_separator に従って候補リスト内のパスを取り出し(この記事の環境は「:」)、そこに含めるファイル名を追加します。このパスの終点を試みます。成功した場合は戻り、そうでない場合は次の候補パスに進みます。
これまでのところ、最初に尋ねた 3 つの質問に答えることができます。
1. ルートディレクトリで実行されるため、1.phpに2.phpがインクルードされている場合、include_pathの第2候補パス(path_to_subdir)が機能し、path_to_subdir/2.phpが見つかりますが、2.phpの場合は3. php がインクルードされている場合、現在の作業ディレクトリは root の下にあるため、3.php がインクルードされている場合、一致するファイルは include_path "." (現在の作業ディレクトリ) の最初の候補パスにあるため、出力は "root" になります。
2. 現在のパスが subdir であることを除き、1 と同じです。したがって、出力は「subdir」になります。
3. 現在のパスに include_path がないため、ルート ディレクトリで実行するときに 2.php が 3.php をインクルードすると、path_to_subdir が役割を果たし、ルートかサブディレクトリかに関係なく "subdir" の出力が得られます。
そして、2.php の include_path をクリアすると、
コードをコピーします コードは次のとおりです:
ini_set("include_path", '');
require("3.php");
?>すると、current_script_dir が有効になり、この時点では current_script_dir は 2.php のパスなので、引き続き "subdir" の出力が得られます。
ディレクトリの相対パス
ディレクトリ相対パスを使用する場合、相対パスの基点は常に現在の作業ディレクトリになります。
ディレクトリ相対パスの状況を説明するために、別の例を見てみましょう。これも上記のディレクトリ構造ですが、1.php は次のようになります。
コードをコピーします コードは次のとおりです:
ini_set("include_path", "/");
require("./subdir/2.php");
?>2.php は次のようになります:
コードをコピーします コードは次のとおりです:
require("./3.php");?>ルートディレクトリで実行した場合、2.php内の3.phpを検索するとカレントディレクトリの相対パスで検索されるため、得られる出力は「root」となり、その上位のサブディレクトリで実行した場合は、レベルディレクトリ 1.php(php -f ../1.php) は、サブディレクトリ
に「./subdir/2.php」が見つからないため、異常終了します。
追記
1. include_path と相対パスを使用する場合、パフォーマンスは検索回数に関係するため、最悪の場合、include_path が 10 個ある場合、含めるファイルを見つけるまでに最大 11 回の再試行が必要になる可能性があります。絶対パスを使用できる場合は、絶対パスを使用することをお勧めします。
2. ディレクトリ相対パスの basedir は常に現在の作業パスとなるため、使用する場合は実際のデプロイメントパスと関連付ける必要があるため、実際には使用されることはほとんどありません (もちろんモジュールもあります) chdir を使用して完了します)。
3. モジュラー システム設計では、通常、モジュールのデプロイメント パスを取得することにより、モジュール内で絶対パスを使用する必要があります (dirname(__file__)、php5.3 以降では __dir__ 定数が提供されます)。
www.bkjia.com