yii框架页面渲染
来源:互联网 发布:c语言标识符是什么 编辑:程序博客网 时间:2024/04/29 17:21
1、一般页面渲染
yii的页面渲染通过在controller的action中调用$this->render($viewname...)进行,流程如下图:
在render方法中,yii会先对你的view文件进行渲染,然后如果你使用了某些layouts,则会将view渲染的输出再传入对layouts的渲染方法中,上述这两步在虚线框中表示了,简单的页面渲染就是这样的。
当然这里面有些技巧需要注意,首先是黑框中显示的那几行代码(位于renderInternal方法中),yii首先启用输出缓冲,并禁止隐式的冲掉缓冲,然后require需要渲染的视图文件,最后再获取缓冲区的全部内容,即最终的渲染结果。这样处理有3个好处:
1.视图文件中多次echo也必须最后一起输出;
2.可以在视图文件中使用$this,即当前的controller对象。
3.第三个好处是这样的,黑框中漏掉了一句“extract($_data_,EXTR_PREFIX_SAME,'data');”,extract函数的作用是将$_data_数组中的$key=>$value对变成当前作用域中的$key = $value赋值,这样视图文件中就可以直接使用$key引用$value的值了。不知道smarty中变量赋值是怎么进行的,但是感觉yii这种方式高效很多,因为不再需要使用php实现词法分析之类的功能了。
这个技巧我们可以自己简单实现一下,就会明白它的原理了。编写代码如下:
class Controller{ private $name=''; public function __construct($name) { $this->name = $name; } public function render($viewName, $data) { extract($data, EXTR_PREFIX_SAME,'data'); ob_start(); ob_implicit_flush(0); require($viewName . '.php'); echo ob_get_clean(); } }$ctrl = new Controller('php');$ctrl->render('view', array('age'=>20)); //模仿render方法调用
echo $this->name . "\n" . $age . "\n"; //view.php只有一句
假设第一段代码存为controller.php,第二段存为view.php(若存为其他名字,请相应修改调用render时传入的名字),在终端执行php controller.php会输出:
php20
本来view.php中是没有$this和$age的,但是因为require时给予了它render方法的作用域,并且采用了extract方法操作传入的数组参数,使得读取这两个变量成为可能。
2、嵌套了layout的视图文件的渲染
这里嵌套是指controller采用了layout1并渲染视图view,而layout1又采用了布局layout2。采用layout1并渲染view是上
一部分的内容,而在layout1中采用layout2是这部分要讲的。采用这种方式进行渲染,通常需要在layout1中调用
controller的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模拟这个渲染过程,编写代码如下:
<?phpclass 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(); ?>
假设第一段代码为dec.php表示装饰器,第二段为layout.php,表示布局文件,运行php layout.php应该会输出:
from Decorator <h1>sddfds</h1>hello这个简化的过程能方便理解框架里的渲染流程。
3、总结
yii的两种渲染过程都有效的利用了语言的输出缓冲,而第二种方式更是通过将“开缓冲”和“取缓冲”的操作分离开,
进而实现了对这两个操作之间的输出内容进行装饰的功能。
- yii框架页面渲染
- yii框架页面渲染
- yii ajax渲染页面
- yii外部action中如何渲染页面
- YII框架修改页面布局
- yii框架404页面的定制
- Yii 渲染与布局(渲染页面的两种方式)
- Yii 渲染与布局(渲染页面的两种方式)
- Yii 视图渲染过程
- YII框架的页面布局的一点心得
- YII 框架 第九天(3)页面缓存
- yii框架实现注册页面短信验证60秒倒计时
- YII框架页面使用frameset布局(一)
- YII框架页面使用frameset布局(二)
- yii框架中jquery实现删除后重定向页面
- yii框架实现注册页面短信验证60秒倒计时
- Yii框架查询Mongodb并页面显示问题
- Yii框架
- UVa 112 - Tree Summing
- 求1-n中数字1出现的次数
- Android应用开发--MP3音乐播放器界面设计(2)
- python基础入门
- fms系列4-在线录制视频、回放
- yii框架页面渲染
- 使用CocoaPods来做iOS程序的包依赖管理
- SQL Server 索引结构及其使用
- acm 2023
- 如何写出专业的C头文件
- Web_find、Web_reg_find和Web_image_check了解多少?
- DATATABLE 和 model 各自的使用场景
- Tomcat虚拟目录配置
- 最快速的Android开发环境搭建ADT-Bundle及Hello World