根据PHP中关于Variable variables的文档:
$this是不能动态引用的特殊变量
然而,它似乎是错误的,至少在我测试过的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注意事项:未定义变量: this
致命错误:在非对象上调用成员函数doSomething()。
注意,语句{'th' . 'is'}
的计算结果是:“未定义的变量: 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
的所有其他动态引用?
发布于 2015-02-10 06:19:07
PHP使用了一个我们称之为编译变量(CV)优化的概念。这意味着,我们不使用将变量名映射到它们的值的哈希表,而是使用普通数组并对其进行索引。编译器知道哪个变量名对应于哪个索引。执行数组索引查找比执行哈希表查找快得多。
$this
变量也将以这种方式存储,并且它的索引被特别地记为op_array->this_var
。如果未找到$this
使用,则在-1
中保留该值为未初始化状态。在将新的执行上下文推送到VM堆栈时,PHP将检查op_array->this_var
,如果不是-1
,则初始化$this
变量条目。
当一个变量被访问时,PHP将遍历CV表,并根据它构造一个适当的符号哈希表。当然,它只会添加实际上在CV表中的变量,所以如果它不包含$this
,那么您将得到一个未定义的变量查找。
现在考虑你的三个案例:
${"th"."is"}
也是一个$this
访问。因此,this_var
在最后一种情况下保持uninitialized.
$this
将被设置,并且也可以通过变量-变量查找来访问。注意,在PHP7中情况是不同的-我们总是在变量变量查找上设置this_var
,所以间接$this
查找应该总是有效的。
https://stackoverflow.com/questions/28419924
复制相似问题