gpt4 book ai didi

php - 重新分配 $this 时的有趣行为

转载 作者:行者123 更新时间:2023-12-04 18:17:23 29 4
gpt4 key购买 nike

我改编了一个很简单的ViewController 传递变量的类至View所以在View我可以直接调用变量,例如

<?php echo $name; ?>

并不是
<?php echo $this->name; ?>

所有 View 变量都存储在一个名为 vars 的关联数组中,例如 $vars['name'] = "test"并拥有 __set分配变量的功能设置,例如
$v = new View;
$v->name="test";
$v->out();

所以在 out()传递变量并包含我添加的 View HTML 的函数:
    foreach($this->vars as $key=>$val) {
$$key=$val;
}
include $this->view_file;

然后我测试了如果我使用 $this 会发生什么在模板中并添加了一个相应的变量,如
$v->this = "test_this";

我的假设是代码将失败,因为 $this无法重新分配或即使重新分配 - see here - 代码将失败,因为 $this已被重新分配,所以
include $this->view_file;

行不通!

相反,它奏效了。 $this , 当使用 echo $this; 直接调用时或 var_dump($this);等于 "test_this"但是 $this->view_file还是指向原值!!

怎么会这样?

然后我使用 extract($this->vars, EXTR_OVERWRITE) 重新测试和 $this没被触动!

一般来说,将变量传递给 View 并避免函数冲突的正确方法是什么
function out($view, $toString = false)
{
extract($this->vars);
include $view;
}

并且 vars 可能有一个名为 view 或 "this"的 var,或者模板可能会使用 $view变种。
  • 别担心,只要确保不要分配一个名为 view 的 var。
  • out() 中使用长变量名函数,如 $longVarNameSoThatThereWillNotBeCollisions .
  • 将函数所需的所有变量分配给 $this->temp : $this->temp['view']然后 unset($view) - 至于$this - 有正常思维的人会使用一个名为 $this 的变量在 View !
  • 最佳答案

    解释为什么您仍然能够访问对象属性,即使您已经设法绕过重新分配的保护 $this ,您必须查看为已编译脚本生成的操作码。

    使用 FETCH_OBJ_R 访问对象属性操作码。

    当您编写诸如

    $myObject = new testClass;
    $myObject->property

    编译后的代码生成 FETCH_OBJ_R两个 参数。第一个是包含对象的变量,第二个是属性的名称。

    如果您使用 Vulcan 反汇编程序,输出可能如下所示:
    FETCH_OBJ_R                                      $1      !1, 'property'
    $1是存储返回值的位置, !1是包含对象的变量。

    但是,如果您使用 $this 访问该属性生成的输出略有不同。
    FETCH_OBJ_R                                      $1      'property'

    带有一个参数的操作码将属性查找解析为从中调用它的对象。

    所以回答你的问题, $this->property在编译时解决。即使你破产了 $thisproperty 的位置已经决定了。

    关于php - 重新分配 $this 时的有趣行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11415760/

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