spController修改成员变量后,模板内不能更新
发布于:2022-01-17 09:50:54
#1 dhs789520
代码如下:
class main extends spController
{
function index(){
$this->title='你好';
$this->title='再见';//此句修改对模板无效
$this->display('index.html');
}
}
分析原因:
模板assign是在spController 中的 __set()函数中设置的
但是修改变量却没有相应代码更新
解决方案:
1.注释掉没用的魔术函数__set()
2.将 private $v ;/应该对代码没有影响吧??
3.在display()中对模板assign赋值
增加代码如下:
$array=get_object_vars($this);
foreach($array as $name => $value){
if(TRUE == $GLOBALS['G_SP']['view']['enabled'] && false !== $value){
$this->v->engine->assign(array($name=>$value));
}
$this->__template_vals[$name] = $value;
}
请问jake老大,这样可好??
我是开发中遇到问题才想改框架的
2011-04-27 11:49:20
#3 dhs789520
回复 2 jake jake老大,貌似上次已经解决了问题,可问题的实质是使用__set()函数的缺陷,所以不能使用此函数为模板赋值,
2011-04-27 12:55:27
#4 jake
这个我还在研究当中,我没觉得__set有什么问题,主要在于语言结构方面的思量。
你可以根据你的需要来改。
对了,你打开PHP的notice就会明白了。
2011-04-27 13:06:45
#5 dhs789520
回复 4 jake 我不知道jake为什么会对一个重要的流程控制漏洞置之不理
一。当新增一个不存在的变量时,通过__set() assign在模板中相应新增一个变量
二。当修改一个已存在的变量时,没有修改模板变量中的值,不是问题吗?
流程应该在display()中设置模板变量,也就是最后
2011-04-27 14:38:08
#6 jake
呵呵,我不明白你希望的是什么?
原生PHP没有规定这样是模板赋值,对吧?
$this->赋值这个方法,是一个框架给出的“规则”,现在考虑的是否修改“规则”,明白吗?
当然,如果你不能理解“规则”和“原生语法”,那么我也无话可说了。
2011-04-27 19:07:08
#7 windman
没觉得有什么问题啊,_set原来就是魔术方法,这个魔术方法的作用就是给没赋值的成员赋值,你
$this->title='你好';//这是第一次赋值,用的是_set
$this->title='再见';//这是第二次赋值,起了作用,但赋值是正常的赋值,没用到_set,当然修改不了,这个相当于变成成员变量了。
2011-04-27 20:36:08
#8 dhs789520
但是你使用smarty模板的时候,模板变量的值就只能是第一次赋的值了,永远不会改变
2011-04-27 20:44:37
#9 dhs789520
回复 6 jake 不知道jake用不用自己的框架,我们总会修改变量值吧,可是修改后的值在”!模板!”中却不能修改,不知道群主可理解我不善于表达的语言?
2011-04-27 20:52:49
#10 windman
这就是_set魔术方法的作用,基本框架都这么做的,方便传值给模板。至于修改值,你方法不对,JAKE在另一贴已经说过,你可以先用临时变量赋值,最后才用$this-title,前面你完全可以用$title
2011-04-27 21:10:13
#11 dhs789520
回复 10 windman 哈哈哈哈,所以我觉得稍微改一下框架,删除__set()函数,在display()中增加模板变量定义就可以完全避免模板内外变量不一致的问题,难道这会制约框架的简约性吗?
2011-04-27 21:22:57
#12 windman
或许不会,但你要明白,一个是给控制器用的普通成员变量,一个是赋给视图用作模板变量的。
你这样不是提前赋值,而是display的时候才赋值,如果多个display呢?重复赋值?
2011-04-27 21:59:00
#13 dhs789520
重复赋值会怎么样?效率低?赋错值又会怎么样?
2011-04-27 22:09:11
#14 windman
效率低不低不知道了,不过你可以看下display的流程,先C的display,再V的display,再到模板引擎的display,不知道你所说的赋错值如何理解
2011-04-27 22:49:58
#15 jake
能否先打开php的notice试过后,才来研究这个问题呢?
这样说吧,我见过另一个框架,它的模板赋值,是通过display的第二个参数传入的,为什么它不用$this->传值呢?这都是规则。
或许这个规则需要改变,但我个人最近没时间,最近有太多的新想法了,希望过了这段时间后能一一实现。请原谅。
这里可以介绍一个很简单的方法,可以达成楼主的想法,就是如同继承于spModel一样,做个继承于spController的类,然后继承重写display,那么就可以做到了。或者说想怎么用都可以。
2011-04-27 23:11:38
#16 dhs789520
回复 15 jake
最近我在反复考虑我发的帖子和我们之间的谈话内容,
发现了一个重要问题,如果一个团队之间沟通出现了问题,那项目基本不会完成
原来我所表达的意思,发到网上来之后却变成了另一个样子了,
所以导致jake的误解,以为我要修改 框架规则,修改$this->的赋值方法,
其实我并不是修改用户的操作,($this->赋值非常好),
也不想在display()函数中增加一个参数,
所以我的目的不是修改框架用户的用户操作方式及用户体验,
用户的操作方式还是和以前一样,$this->赋值
用户不在display()中增加任何参数
用户不修改任何代码
而是框架设计者在spController中修改后台代码,
1.让$this->赋值在刚赋值的时候遵守php语法的严格性,并且成为spController中的成员变量
2.__set() 函数对新建的成员变量不直接赋值给smarty模板,
因为spController类中的变量在display()函数前都有被用户更改的可能性
而更改成员变量并没有在spController的代码中对smarty中的变量做相应操作
3.所以我觉得通过在spController中的display函数中增加代码,让用户在display()时
再查找所有的成员变量给smarty模板赋值.
关键代码:
/**
* 输出模板
*
* @param $tplname 模板路径及名称
* @param $output 是否直接显示模板,设置成FALSE将返回HTML而不输出
*/
public function display($tplname, $output = TRUE)
{
//水哥新增加代码部分
//获得所有public成员变量,赋值给模板
$array=get_object_vars($this);
foreach($array as $name => $value){
if(TRUE == $GLOBALS['G_SP']['view']['enabled'] && false !== $value){
$this->v->engine->assign(array($name=>$value));
}
$this->__template_vals[$name] = $value;
}
//ends of 水哥
@ob_start();
if(TRUE == $GLOBALS['G_SP']['view']['enabled']){
$this->v->display($tplname);
}else{
extract($this->__template_vals);
require($tplname);
}
if( TRUE != $output )return ob_get_clean();
}
2011-05-02 07:53:02
#17 jake
好的,楼上的意见很好,我明白楼上的意思。
不过,这里需要时间研究一下,毕竟此问题的讨论比较多,希望楼上别介意。
任何一个提出的问题,我从来没有说过不修改,但是也没说过一提就改。
另外,感谢一下楼上的坚持:)
2011-05-02 23:47:23