【问题标题】:What does each pass of the PHP interpreter process?PHP 解释器的每一步都处理什么?
【发布时间】:2016-09-08 12:08:08
【问题描述】:

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

代码方面:

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 程序员,所以任何信息都非常感谢。

【问题讨论】:

  • 你试过if (class_exists('X')) {class X {…}}吗?
  • A.L. - 那行不通。这种方法适用于 javascript 或 ruby​​,但不适用于 PHP。在 PHP 中,即使在 if-loop 中也定义了类。最好使用命名空间以避免名称冲突或将每个类放入单独的文件并使用自动加载php.net/manual/en/language.oop5.autoload.php
  • 据我所知,我现在正在做的事情。我对每次通过时发生的处理的解释是否正确?有没有可以参考的地方?
  • 不,没有用。我使用了 require_once 建议并将类和函数定义移入其中。现在事情似乎奏效了。但我仍在寻找 PHP 在解释器的每次传递中所做的参考。
  • 轻微更新 - 仍然有问题。现在该类在一个 require_once 中,而函数在另一个中。

标签: php php-internals


【解决方案1】:

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

然后你可以将你的代码分成两个文件:

  1. 在可以多次调用的文件中添加include_once
  2. X类移动到另一个文件中,这个新的填充将包含在1中添加的include_once中。

这样,2. 文件将只包含一次,即使 1. 文件被多次调用。

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

【讨论】:

  • 这是一个很好的建议,但没有回答我的问题 - 每次传递都会处理什么?
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多