我调整了一个非常简单的View
类来将变量从Controller
传递到View
,以便在View
中我可以直接调用变量,例如。
<?php echo $name; ?>
而不是
<?php echo $this->name; ?>
所有视图变量都存储在名为vars的关联数组中,例如$vars['name'] = "test"
并设置__set
功能设置以分配变量,例如
$v = new View;
$v->name="test";
$v->out();
所以在传递变量的out()
函数中包含我添加的视图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
没有被触及!
通常,将变量传递给视图并避免函数中的冲突是正确的方法
function out($view, $toString = false)
{
extract($this->vars);
include $view;
}
和vars可能有一个名为view或“this”的var,或者模板可能会使用$view
var。
out()
函数中使用长变量名称,例如$longVarNameSoThatThereWillNotBeCollisions
。$this->temp
:$this->temp['view']
然后unset($view)
- 以及$this
- 正确思维的人将使用名为的变量$this
中的View
!答案 0 :(得分:4)
要解释为什么您仍然能够访问对象属性,即使您已设法绕过重新分配$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
在编译时得到了解决。即使您中断了$this
,property
的位置也已经确定。
答案 1 :(得分:0)
这让我感兴趣,看起来你是对的,使用变量赋值给$this
时可能会出现错误。
正如你正确地说:
<?php
$var = 'this';
$$var = 'hello';
echo $this;
有效,而
<?php
$this = 'hello';
echo $this;
不
也许在bugs.php.net上报告,看看是否有正式答案?
$this
的现有成员仍在工作,而$this
的实际价值完全不同的事实绝对不应该发生,而且必须是某种形式的核心问题。我唯一能想到的是,不知怎的$this
被用作神奇的上下文变量(当然不奇怪,它是PHP的后缀!)而不是真正的“真正的”变量。从变量变量赋值的错误(显然应该不!)允许$this
是一个虚假变量显示给开发人员的事实。
魔力测试:
<?php
class ThisTest {
public function SetAndUseThis() {
$var = 'this';
$$var = 'that';
var_dump($this);
var_dump($this->variable);
var_dump($this->AnotherMethod());
}
public $variable = 'i am a variable';
public function AnotherMethod()
{
return 9.0;
}
}
$inst = new ThisTest();
$inst->SetAndUseThis();
结果:
string(4) "that" string(15) "i am a variable" float(9)