14

PHPエンジンによる関数宣言の解釈の順序について疑問に思っています。somethimes PHPが未定義関数への呼び出しの致命的なエラーを表示し、somethimesインタープリターが問題なく関数を表示する理由がわかりません。

私のコードが次のようになっているとしましょう:

echo theRest(4,3);

function theRest($a, $b)
{
   return $a % $b;
}

関数が呼び出し後に宣言され、これが適切に機能することを確認してください。これは、PHPが解釈の前にファイル全体を読み取ることを意味しますか?

もう一つの例:

echo theRest(4,3);

include('test2.php');

test2.php

function theRest($a, $b)
{
    return $a % $b;
}

ここで致命的なエラーが発生します:未定義の関数theRest()を呼び出します。何故ですか?

4

3 に答える 3

9

PHPが解釈前にファイル全体を読み取っていることを意味しますか?

はい、PHPは一度に1つのファイルを解析します。また、「include」はステートメントであり、コンパイル時に発生するものではないため、インクルード行に達するとすぐにインクルードされたファイルが解析されます。一方、関数定義はステートメントではなく、制御構造内にある場合を除いて、コンパイル時に処理されます。これが、以下が機能する理由です。

if (!function_exists('ucwords')) {
    function ucwords($str) {
        //...
    }
}

したがって、解析され、制御構造の外部にあるファイル内のすべての関数とクラスの定義は、すぐに利用できます。

于 2013-03-11T09:42:00.073 に答える
8

PHPはファイルを読み取るときに、ファイルをバイトコード(コンパイル時)にコンパイルしてから実行します(実行時間/実行時間)。

無条件の関数宣言はコンパイル時に読み取られるため、コードの実行時に関数はすでに認識されています。

一方、インクルードは実行時に実行されるため、インクルードファイルで定義された関数は、include()それ自体が実行される前は使用できません。引数は動的である可能性があり(たとえば) 、コードによって変更される可能性のある設定include $path_to_file;に依存するため、コンパイル時にインクルードを実行することはできません。include_path

ドキュメントはそれについて非常に明確です:

以下の2つの例に示すように関数が条件付きで定義されている場合を除き、関数は参照される前に定義する必要はありません。

を使用する場合include()、関数は事実上条件付きで定義されます(たとえば、設定include "foo.php";に応じて1つのファイルまたは他のファイルを含めることができますinclude_path)。

于 2013-03-11T09:41:04.550 に答える
0

このコードでは:

echo theRest(4,3);

function theRest($a, $b)
{
   return $a % $b;
}

最初に全体がコンパイルされてから、コードが実行されます。ただし、このコードでは:

echo theRest(4,3);

include('test2.php');

ステートメント自体はコンパイルされますが、コードがそのinclude実行ポイントに到達するまで実行されません。

参照されるポイントの前に配置すると、include次のように修正されます。

include('test2.php');

echo theRest(4,3);
于 2013-03-11T09:54:37.057 に答える