PHP解释器进程的每次传递是什么?

时间:2016-05-12 14:56:00

标签: php php-internals

我有一个定义类的包含文件,然后创建一个具有该类实例的全局,以及一个返回全局的函数(用于在其他函数中访问)。

代码明智:

class X {
    ...
}

global $x;
$x = new X();

function x() {
    global $x;
    return $x;
}

到目前为止,一切似乎都很好。然后有一种情况(显然)这个文件不止一次被包含 - 它由框架完成,所以我不能将它限制为include_once - 这会导致尝试重新定义类的错误。

所以我在顶部添加了代码:

if (class_exists('X')) {
    return;
}

我发现$ x已不再定义。因此,似乎解释器必须运行一次,找到类定义,但不处理后面的语句。然后它似乎进行第二次传递并发现该类存在,因此它返回时不会执行类实例化。

所以我将顶部的代码更改为:

if (class_exists('X')) {
    global $x;
    $w = new X();

    function x() {
        global $x;
        return $x;
    }
    return;
}

现在我在尝试重新声明该函数时遇到错误(原始声明仍然在文件的底部)。所以,即使实例化X的代码没有被执行,函数也被定义了。

所以文件的顶部现在看起来像这样:

if (class_exists('X')) {
    global $x;
    $w = new X();

    if (function_exists('x')) {
        return;
    }

    function x() {
        global $x;
        return $x;
    }
    return;
}

所以现在一切正常,因为它似乎应该。

基于我所看到的,我最好的猜测是解释器发出一个收集类和函数定义的传递,然后使用这些定义进行另一个执行代码的传递。这种解释是否正确?我缺少细微差别吗?

我不是任何专业的PHP程序员,所以任何信息都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

  

然后有一种情况显然(显然)这个文件不止一次被包含 - 它是由框架完成的所以我不能将它限制为include_once

然后您可以将代码拆分为两个文件:

  1. 在可以多次调用的文件中添加include_once
  2. X类移到另一个文件中,这个新的邮件将包含在1中添加的include_once中。
  3. 这样,即使多次调用1.文件,2.文件也只包含一次。

    您应该使用require_once(而不是include_once),因为如果找不到该文件,它将返回错误。