- 浏览: 331254 次
- 性别:
- 来自: 北京
博客专栏
-
高性能PHP框架Yii分析...
浏览量:83935
文章分类
最新评论
-
huxiaoyunhust:
价值观这种东西,说不好听是口号,其实是公司每天潜移默化的感染, ...
关于企业价值观的一点点感悟 -
silentime:
stef831018 写道你想多了,企业价值观就两个字:利益怎 ...
关于企业价值观的一点点感悟 -
stef831018:
你想多了,企业价值观就两个字:利益
关于企业价值观的一点点感悟 -
guoyuqiangf8:
关于企业价值观的一点点感悟 -
silentime:
mangguo 写道推荐大家去看看我写的python入门,可以 ...
python如何打印变量的类型
《The Definitive Guide to Yii》描述了视图的概念:“视图是一个包含了主要的用户交互元素的PHP脚本.他可以包含PHP语句”,不同于很多类似的框架,Yii并没有使用smarty作为模板引擎,而是直接使用原生的PHP脚本作为模板,笔者认为至少有以下两点好处:
(1) 门槛低,易于使用,不需要理解和记忆smarty的模板语言语法
(2) 减少了模板引擎解析的过程,直接include,结合opcode缓存,效率可能会更高
当然也有缺点:
(1) 没有smarty的前端过滤功能,前后端分离开发也有一定的门槛(前端工程师需要学习PHP语法,尤其是字符串处理相关函数)
(2) 直接使用PHP,对于一些约束很难控制,比如全局的错误级别,如何控制逻辑处理与数据处理的界限?
因此,对于是使用PHP原生脚本还是使用smarty作为模板各有利弊,不论程序开发人员使用哪一种,都要了解这种方式的利弊才能更加安全有效地进行开发。
在Yii中,显示一个视图非常简单,即调用Ccontroller的方法render:
$this->render(‘viewName’);
而这个过程是如何实现的呢?我们看看render这个方法的源码:
/** * 使用框架来渲染一个视图 * * 这个方法首先调用{@link renderPartial}来渲染视图 (内容视图) * 然后渲染框架视图(在合适的位置嵌入内容视图) * 在框架视图中,内容视图的渲染结果以变量的方式来访问 * 最后,调用{@link processOutput}在可用时来插入脚本 * 和动态内容 * * 默认的框架视图位置为:"protected/views/layouts/main.php". * 可以通过设置{@link layout}.来自定义 * * @param string $view 要被渲染的视图名称See {@link getViewFile} for details * about how the view script is resolved. * @param array $data 在视图中被解析为PHP变量的数据 * @param boolean $return 返回渲染的结果或者直接显示给最终用户 * @return string the rendering result. Null if the rendering result is not required. * @see renderPartial * @see getLayoutFile */ public function render($view,$data=null,$return=false) { //触发beforeRender事件,beforeRender直接返回true(子类覆盖自定义) if($this->beforeRender($view)) { //将$view的内容渲染后返回给变量$output $output=$this->renderPartial($view,$data,true); if(($layoutFile=$this->getLayoutFile($this->layout))!==false) //将$output作为数据渲染整个框架 $output=$this->renderFile($layoutFile,array('content'=>$output),true); //afterRender是一个空函数,子类覆盖自定义 $this->afterRender($view,$output); //处理输出 $output=$this->processOutput($output); //返回or直接输出 if($return) return $output; else echo $output; } }
在render的过程中,用到了另外render函数:renderPartial和renderFile,renderPartial是CController的一个成员函数:
/** * 渲染一个视图 * * 视图名,指向一个PHP脚本通过{@link getViewFile}解析 * 如果$data是一个数组,会被解析为PHP的变量 * 可以在视图脚本中使用 * * 这个方法不同于{@link render(),他不会使用框架(layout)来渲染 * 常用来渲染一个视图的一部分,或者AJAX响应 * * @param string $view 被渲染的视图名称{@link getViewFile} * @param array $data 被解析为PHP变量的数据,在视图脚本中可用 * @param boolean $return 渲染的结果是否被返回,否则直接展示给最终用户 * @param boolean $processOutput 是否使用{@link processOutput}来处理渲染结果 * @return string 渲染结果 * @throws CException 如果视图不存在会抛出异常 * @see getViewFile * @see processOutput * @see render */ public function renderPartial($view,$data=null,$return=false,$processOutput=false) { //获取视图路径 if(($viewFile=$this->getViewFile($view))!==false) { //调用renderFile来返回渲染结果 $output=$this->renderFile($viewFile,$data,true); if($processOutput) $output=$this->processOutput($output); //返回or直接显示 if($return) return $output; else echo $output; } else throw new CException(Yii::t('yii','{controller} cannot find the requested view "{view}".', array('{controller}'=>get_class($this), '{view}'=>$view))); }
renderFile并不是在CController中定义的,而是在CController的父类CBaseController中定义:
/** * 渲染一个视图文件 * * @param string $viewFile 视图文件路径view file path * @param array $data 解析为变量的数据 * @param boolean $return 是否返回渲染结果 * @return string 渲染结果 * @throws CException if the view file does not exist */ public function renderFile($viewFile,$data=null,$return=false) { $widgetCount=count($this->_widgetStack); //获取renderer类,同时检查视图文件扩展名,默认情况下,是没有自定义的viewRenderer对象的,Yii内置了抽象类CViewRenderer,如果自定义可以继承这个类 if(($renderer=Yii::app()->getViewRenderer())!==null && $renderer->fileExtension==='.'.CFileHelper::getExtension($viewFile)) //如果renderer的扩展名与视图文件扩展名相同 $content=$renderer->renderFile($this,$viewFile,$data,$return); else //调用renderInternal $content=$this->renderInternal($viewFile,$data,$return); //使用widget的堆栈计数,如果与widgetCount不一致,说明没有调用endWidget()来释放 if(count($this->_widgetStack)===$widgetCount) return $content; else { $widget=end($this->_widgetStack); throw new CException(Yii::t('yii','{controller} contains improperly nested widget tags in its view "{view}". A {widget} widget does not have an endWidget() call.', array('{controller}'=>get_class($this), '{view}'=>$viewFile, '{widget}'=>get_class($widget)))); } }
renderInternal代码如下:
public function renderInternal($_viewFile_,$_data_=null,$_return_=false) { // we use special variable names here to avoid conflict when extracting data if(is_array($_data_)) //如果data是数组,使用extract extract($_data_,EXTR_PREFIX_SAME,'data'); else //如果不是数组,直接赋给$data变量 $data=$_data_; //如果需要返回,使用ob进行缓冲输出,之后再返回,否则直接调用require(如果文件不存在,会导致一个fatal error) if($_return_) { ob_start(); ob_implicit_flush(false); require($_viewFile_); return ob_get_clean(); } else require($_viewFile_); }
接着,我们来看一下在渲染玩view文件之后,处理输出的过程:
/** *由{@link render()}调用处理最后的输出 * 这个方法在{@link render()}和{@link renderText()}的结尾调用 * 如果有注册的客户端脚本,这个方法会把他们在合适的位置 * 插入到输出中。如果有动态内容,也会被插入 * 这个方法可能会在页面的隐藏状态窗口中保存页面的持久状态 * @param string $output 由当前action产生的输出 * @return string 处理过的输出 */ public function processOutput($output) { //插入客户端脚本 Yii::app()->getClientScript()->render($output); // 如果使用了页面缓存,我们可以延迟动态内容的替换 if($this->_dynamicOutput!==null && $this->isCachingStackEmpty()) $output=$this->processDynamicOutput($output); //页面状态的处理 if($this->_pageStates===null) $this->_pageStates=$this->loadPageStates(); if(!empty($this->_pageStates)) $this->savePageStates($this->_pageStates,$output); return $output; } public function processDynamicOutput($output) { if($this->_dynamicOutput) { //使用正则替换特殊字符 $output=preg_replace_callback('/<###dynamic-(\d+)###>/',array($this,'replaceDynamicOutput'),$output); } return $output; }
至此,整个render过程已经完成,总结下来,主要经历了数据解析和require,加载客户端脚本和动态数据两部分。
评论
发表评论
-
[转]PHP的内存管理
2015-05-11 22:03 832原文出处:http://blogread.cn/it/ar ... -
《高性能PHP应用开发》读书笔记
2014-12-24 09:20 758注:只记录了一些关键点,部分知识点/内容请看到的朋友 ... -
HTTP API Design Guide(HTTP API接口设计指南)
2014-09-09 18:27 3451原文在这里:https://github.com/inte ... -
IE系列不支持圆角等CSS3属性的解决方案
2013-07-23 23:38 1228IE系列浏览器不支持CSS的圆角(border-radius ... -
[转]HTTP缓存算法
2013-01-04 14:34 1256原文地址:http://www.p ... -
【转】漫谈社区PHP 业务开发
2012-11-19 10:07 1070原文地址:http://stblog.baidu-tech.c ... -
【转】javascript中的urlencode
2012-09-20 23:04 1109原文地址:http://www.cnblo ... -
Yii分析13:Yii核心组件之AssetManager
2012-04-10 00:37 4342我们通过使用来讲解CAssetManager的使用和工 ... -
Yii分析12:Yii核心web组件之会话类CHttpSession
2012-03-06 09:44 3191CHttpSession提供session级的数据管理和配置 ... -
Yii分析11:Yii核心组件之错误处理类CErrorHandler
2012-02-24 09:57 4037类如其名,CErrorHandler在Yii中主要的功能 ... -
Yii分析10:Yii核心组件之数据库类CDbConnection
2012-02-17 09:18 8459数据库类几乎是每个PHP框架必不可少的组件之一,Yii的 ... -
Javascript面向对象之十装饰者模式-《javascript设计模式》笔记
2012-01-18 14:59 1430装饰者模式的含义是将要装饰的对象作为一个成员放在装饰者的内部, ... -
Javascript面向对象之九适配器模式-《javascript设计模式》笔记
2012-01-18 14:58 1218关于适配器模式的定义:适配器模式(有时候也称包装样式或者包装) ... -
Javascript面向对象之八门面模式-《javascript设计模式》笔记
2012-01-17 14:43 1285关于门面模式的定义:门面模式为了系统提供一个 统一的高层接口供 ... -
Javascript面向对象之七组合模式-《javascript设计模式》笔记
2012-01-17 14:42 1307关于组合模式的定义:组合模式(Composite Patter ... -
Javascript面向对象之五工厂模式-《javascript设计模式》笔记
2012-01-13 11:31 1164工厂模式和单例模式(http://blog.sina.com. ... -
Javascript面向对象之四链式调用-《javascript设计模式》笔记
2011-12-30 14:22 13351.链式调用:jquery可能是目前大家最常用到的js框架了, ... -
Javascript面向对象之三单例模式-《javascript设计模式》笔记
2011-12-30 14:21 12751.单例模式概述源自百 ... -
Javascript面向对象之二继承-《javascript设计模式》笔记
2011-12-29 10:49 11271.关于继承:百度百科对继承的解释是:继承是指一个对象直接使用 ... -
Javascript面向对象之一对象成员的定义-《javascript设计模式》笔记
2011-12-29 10:48 1641序: 刚接触javascript的时候,觉得这语言有点儿 ...
相关推荐
Yii护照 安装 :light_bulb: 这是展示如何安装软件包的好地方,请参见下文: 跑步 $ composer require inquid/yii-passport 用法 :light_bulb: 这是显示一些用法示例的好地方! 变更日志 请看看 。 贡献 请看看 。...
yii2elfinder 感谢: : 感谢:zybodya 提供当前 yii 版本 yii2elfinder 介绍:旧版本无法使用,因为它完全不适用于最新的jquery版本! 所以除了行动,我不得不改变一切;) 这个扩展允许你将 ElFinder 文件管理...
Yii 框架的 HAML 视图渲染器 yii-haml是扩展,它为您的视图带来了功能。 基于项目的分支。 使用 Composer 安装 将此添加到您的composer.json : " repositories " : [ { " type " : " composer " , " url " : ...
yii2sly 这个扩展是惊人的 jquery 滑块“sly”的包装器,可以在这里找到: 请。 仔细查看所有插件选项,可以通过将它们添加到“clientOptions”参数来传递这些选项,如下所示。 可以在此处找到扩展的演示: 安装 ...
PHP的Yii框架中创建视图和渲染视图的方法详解_.docx
yii-simplepie yii-simplepie 是用于解析 rss 提要的 yii 扩展: 简单派: simplepie 文档: 用法 在 yii 中安装扩展 下载所有文件并放入 yii 扩展文件夹,然后在 config/main.php 中添加以下代码 'simplepie' ...
Yii-QA简介(此项目目前已不再维护)感谢选择Yii-QA,基于框架基础实现的问答程序。 #意识到目前的急性时间有限,无法管理太多的额外项目,我准备合并现有手上的项目,集成在一个项目中,感谢支持!!!!!!!请关注:...
用于与支付的 api 配合使用的 Yii 组件 安装 从这个 github 存储库下载 yii-robokassa: cd protected/components git clone https://github.com/ladamalina/yii-robokassa.git 在 protected/config/main.php 中...
yii2-swoole 为赋予 Yii2 框架协程异步能力而生。 后期开发会依赖 去实现功能,相信 Swoft 会是下一代优秀的框架。 此插件基于 swoole (v2.0) 底层实现的协程,改造 Yii2 的核心代码,使开发者无感知,以及在不改动...
yii-seo Yii PHP 框架的搜索引擎优化。 用法 布局中 <?php Yii::app()->controller->widget( 'vendor.crisu83.yii-seo.widgets.SeoHead', array( 'httpEquivs' => array( 'Content-Type' => 'text/html; ...
Yii 框架的 CKEditor 小部件 简单的 Yii CKEditor 小部件。 CKEditor - 每个人的 WYSIWYG 编辑器。 小部件生成具有相同属性的 CHtml::activeTextArea。 使用 CKEditor 4+ 版本测试。 安装 将此小部件复制到扩展...
Yii 1 流日志 将 Yii 1 日志发送到 stdout/stderr - 创建用于与提供的 php-fpm/nginx Docker 堆栈一起使用 感谢 Haensel 为! 安装 通过作曲家安装: composer require neam/yii-streamlog:* 或者下载扩展,将src...
Arshaw 的 FullCalendar jQuery 插件的 Yii 扩展 作者:Alexey Samoylov ( )。 要求 PHP 5.4 Yii 1.x 例子 全局组件配置示例: 'components' => [ 'fullcalendar' => [ 'class' => 'ext.yii-fullcalendar....
具体来说,控制器从应用主体接管控制后会分析请求数据并传送到模型, 传送模型结果到视图,最后生成输出响应信息。 操作 控制器由 操作 组成,它是执行终端用户请求的最基础的单元,一个控制器可有一个或多个操作。...
yii2-schemadump 从现有数据库生成模式。... ], 'controllerMap' => [ 'migrate' => [ 'class' => yii\console\controllers\ MigrateController ::class, 'templateFile' => '@jamband/schemadump/template.php' ,
yii2fullcalendar JQuery Fullcalendar Yii2扩展JQuery来自: ://arshaw.com/fullcalendar/版本4.0.2许可证MIT jQuery文档: //arshaw.com/fullcalendar/docs/ Yii2扩展,通过 可以在这里找到一个小样本:http: ...
封装Yii函数,便于非Yii开发人员创建插件 模块使用 安装 将这些数组添加到项目配置中(如果您有多个条目,请将它们都添加到两者中) 'components' => array( 'plugin' => array( 'class' => 'application....
Yii框架演示项目 [Yii Framework]是一个现代框架,旨在为您PHP应用程序奠定坚实的基础。 它旨在显示和测试所有Yii功能。 安装 您至少需要PHP 7.4。 克隆此存储库。 在项目根目录中运行composer update 。 运行./...
yii-进程锁 防止脚本的多个副本同时运行。 使用 composer.json依赖项: " happyproff/yii-processlock " : " * " 注册应用程序组件: 'components' => [ . . . , 'processLock' => [ 'class' => '...
Yii 2 高级应用模板 Yii 2 Advanced Application Template 是一个骨架 Yii 2 应用程序,最适合开发具有多层的复杂 Web 应用程序。 模板包括三层:前端、后端和控制台,每一层都是一个独立的 Yii 应用程序。 该模板...