gpt4 book ai didi

php - 动态引用 $this 不应该工作,但它确实

转载 作者:IT老高 更新时间:2023-10-28 12:09:34 25 4
gpt4 key购买 nike

根据关于 Variable variables 的 PHP 文档:

$this is a special variable that cannot be referenced dynamically

不过好像是假的,至少在PHP的版本上,我测试过(5.5.12)。

class ThisIsBugged
{
public function __construct()
{
${'this'}->doSomething(); // This works, while it shouldn't
}
}

问题 #1:它是如何工作的?根据文档,它不应该。

但还有更多。

class ThisIsBugged
{
public function __construct()
{
// This does not work, but it could. See below.
${'th' . 'is'}->doSomething();
}
}

它按预期停止执行:

PHP Notice: Undefined variable: this

PHP Fatal error: Call to a member function doSomething() on a non-object.

注意语句 {'th' 。 'is'} 已被评估:“ undefined variable :this”.

但是(这是最奇怪的事情),显式引用特殊变量 $this,修复了方法中之前或之后使用的所有动态引用。

class ThisIsBugged
{
public function __construct()
{
// Now it works while it shouldn't
${'th' . 'is'}->doSomething();

// This fixes both the previous and the subsequent calls
$unused = $this;

// Now it works while it shouldn't
${'th' . 'is'}->doSomething();
}
}

问题 #2:对 $this 的显式引用如何修复整个方法中对 $this 的所有其他动态引用?

最佳答案

PHP 使用我们称为编译变量 (CV) 优化的概念。这意味着我们不使用将变量名称映射到它们的值的哈希表,而是使用普通数组并对其进行索引。编译器知道哪个变量名对应哪个索引。执行数组索引查找比执行哈希表查找要快得多。

$this 变量也将以这种方式存储,并且它的索引被特别记住为 op_array->this_var。如果未找到 $this 使用,则该值在 -1 处未初始化。当将新的执行上下文推送到 VM 堆栈时,PHP 将检查 op_array->this_var,如果不是 -1,则初始化 $this 变量入口。

当一个变量变量被访问时,PHP 将遍历 CV 表并从中构造一个适当的符号哈希表。当然它只会添加实际在 CV 表中的变量,所以如果它不包含 $this 你最终会得到一个 undefined variable 查找。

现在考虑你的三种情况:

  1. $this${"this"} 就 PHP 编译器而言是相同的(毕竟变量名在编译时都是已知的例)。
  2. 由于 PHP 5.x 编译器尚未执行常量表达式折叠,因此它无法检测到 ${"th"."is"}$这个 访问也是如此。所以 this_var 保持未初始化状态。
  3. 在最后一种情况下,您有一个普通的 $this 用法,因此 this_var 将被设置并且也可以通过变量-变量查找进行访问。

请注意,PHP 7 中的情况有所不同 - 我们将始终在变量查找中设置 this_var,因此间接 $this 查找应该始终有效。

关于php - 动态引用 $this 不应该工作,但它确实,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28419924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com