dynamic引用$这不应该工作,但它
根据有关variablesvariables的 PHP文档:
$这是一个不能dynamic引用的特殊variables
不过,至less在PHP的版本中,它似乎是错误的,我testing过(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注意:未定义variables:this
PHP致命错误:调用一个非对象的成员函数doSomething()。
请注意,语句{'th' . 'is'} {'th' . 'is'}已被评估: “未定义variables:this” 。
然而(这是最奇怪的事情),显式引用特殊variables$this ,修复在该方法之前或之后使用的所有dynamic引用。
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的dynamic引用?
PHP使用我们称之为编译variables(CV)优化的概念。 这意味着我们不使用将variables名映射到其值的散列表,而是使用一个普通的数组和索引。 编译器知道哪个variables名称对应于哪个索引。 执行数组索引查找比使用散列表查找要快得多。
$thisvariables也将以这种方式存储,其索引被特别记住为op_array->this_var 。 如果没有$this使用被发现这个值保持未初始化在-1 。 将新的执行上下文推送到VM栈时,PHP将检查op_array->this_var ,如果不是-1 ,则初始化$thisvariables条目。
当访问一个variablesvariables时,PHP将遍历CV表并从中构造一个适当的符号散列表。 当然,它只会添加实际存在于CV表中的variables,所以如果它不包含$this那么最终会得到一个未定义的variables查找。
现在考虑你的三种情况:
-
$this和${"this"}与PHP编译器相同(在这两种情况下编译时已知所有的variables名)。 - 由于PHP 5.x编译器尚未执行常量expression式折叠,因此它将无法检测到
${"th"."is"}是否为$this访问。 所以this_var保持未初始化。 - 在最后一种情况下,您有一个简单的
$this用法,因为这样的this_var将被设置,并且也可以通过variablesvariables查找来访问。
请注意,PHP 7中的情况有所不同 – 我们将始终将this_var设置为variablesvariables查找,因此间接$this查找应始终工作。