beginContent(layout2)
方法,并传入layout2的名称,然后在渲染结束后再调用controller的endContent()
方法结束渲染过程。伪码如下:
<?php // $this is the controller $this->beginContent('layout2'); ?> some html and/or <?php echo $content; ?> <?php $this->endContent(); ?>
这里就要讲这两个方法以及整个过程的实现机制。先来看beginContent的工作流程:
请注意这一连串的过程都是在当前controller的作用域进行的。可以看到beginContent调用beginWidget并传入了一个类名,这个类的实例就是后面的widget,表示了一个装饰器,注意在createWidget时传入了当前controller的实例,并且会对widget的view属性赋值为layout名称(这里的过程还要稍微复杂些,但是大致的意图是这样的,具体可参考源码),这两个变量后面有用;然后调用widget的Init方法使其初始化,并将其缓存到controller的一个stack中。值得注意的是init方法里做了什么:很熟悉,打开了输出缓冲区。用途是什么,看了第一部分你应该懂~~下面再看endContent的执行过程:
这个过程稍微复杂些,先说明一直到第一个虚线框(包括)都是在当前controller的作用域,之后都是在widget的作用域了。可以看到调用endContent之后其实先从controller的那个stack中弹出了先前保存的widget,然后调用widget的run方法。之后就主要是widget的工作了,首先是熟悉的ob_get_clean()拿到缓冲区中的内容,参考伪码你会明白,此时缓冲区中的内容是“some html and/or ...”,即你写的页面html和要echo出的东西;然后重要的工作在decorate方法中,它会通知controller去获取layout文件,并通知controller渲染这个文件,但是controller在哪儿?就是widget的owner属性,表示谁拥有这个widget,还记得在beginContent中向widget实例传入了controller对象吧?:) 之后的过程就简单了,跟渲染普通视图文件一样,只不过这里会将从缓冲区得到的内容全部传给视图文件,并获取最终的渲染结果。
同样的,我们也可以写个demo模拟这个渲染过程,编写代码如下:
<?php class Decorator { public function begin() { ob_start(); ob_implicit_flush(0); } public function decorate($content) { echo 'from Decorator ' . $content; } public function end() { $output = ob_get_clean(); $this->decorate($output); } } ?>
require_once('dec.php'); $dec = new Decorator(); $dec->begin(); ?> <h1>sddfds</h1> <?php echo 'hello'; ?> <?php $dec->end(); ?>
内容版权声明:除非注明,否则皆为本站原创文章。