Yii核心组件AssetManager原理分析


Posted in PHP onDecember 02, 2014

本文我们通过yii自带的demo-blog程序来分析Yii核心组件AssetManager,他可以自动加载css和javascript,并且只需要一句代码即可。具体分析如下:

打开blog的首页,会看到如下的引入js的html代码:

<link rel="stylesheet" type="text/css" href="/yii/demos/blog/assets/d6bb6ebe/highlight.css" />

<link rel="stylesheet" type="text/css" href="/yii/demos/blog/assets/c2e28f0f/pager.css" />

<script type="text/javascript" src="/yii/demos/blog/assets/d6112c6a/jquery.min.js"></script>

<script type="text/javascript" src="/yii/demos/blog/assets/d6112c6a/jquery.ba-bbq.js"></script>

这些js文件的路径都在assets文件夹下,assets后面跟着一个显然经过hash的文件夹路径,同属于jq的js代码的路径相同,这段代码从何而来呢?

直接看view文件看不到任何引入js的代码,因此应该是使用widget引入的:

<?php

$this->widget('zii.widgets.CListView', array(

'dataProvider'=>$dataProvider,

'itemView'=>'_view',

'template'=>"{items}n{pager}",

));

?>

这个widget也是yii自带的zii扩展,于是乎我们可以找到zii的CListView代码,而CListView又是继承CBaseListView,因此先看CBaseListView的run方法:

public function run()

{

$this->registerClientScript();

echo CHtml::openTag($this->tagName,$this->htmlOptions)."n";

$this->renderKeys();

$this->renderContent();

echo CHtml::closeTag($this->tagName);

}

请注意第一个方法registerClientScript,这个方法是在CListView中实现的:

public function registerClientScript()

{

……

$cs=Yii::app()->getClientScript();

$cs->registerCoreScript('jquery');

$cs->registerCoreScript('bbq');

……

}

看到jquery和bbp似乎离真相近了些,接下来我们看CClientScript::registerCoreScript方法:

public function registerCoreScript($name)

{

$this->_hasScripts=true;

$this->_coreScripts[$name]=$name;

$params=func_get_args();

$this->recordCachingAction('clientScript','registerCoreScript',$params);

}

这里其实主要是记录了最终页面要render的js,而实际生成render的url是通过getCoreScriptUrl方法:

public function getCoreScriptUrl()

{

if($this->_baseUrl!==null)

return $this->_baseUrl;

else

return $this->_baseUrl=Yii::app()->getAssetManager()->publish(YII_PATH.'/web/js/source');

}

接下来我们看看publish的具体过程:

public function publish($path,$hashByName=false,$level=-1,$forceCopy=false)

{

if(is_file($src))

{

$dir=$this->hash($hashByName ? basename($src) : dirname($src));

$fileName=basename($src);

……

else if(is_dir($src))

{

$dir=$this->hash($hashByName ? basename($src) : $src);

$dstDir=$this->getBasePath().DIRECTORY_SEPARATOR.$dir;

……

}

这里通过对路径做了hash处理,因此我们看到的路径是不规则的,而由于jq系列的js代码均在同一路径下(都在framework/web/js/source下),所以hash值是相同的。

另外,除了如上所述,CAssetManager使得多个模块可以复用相同的代码制外,使用CAssetManager的另外一个好处是安全隔离,将真实的代码放在受保护的路径下,按需加载。

希望本文所述对大家基于yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
第六节 访问属性和方法 [6]
Oct 09 PHP
php adodb连接带密码access数据库实例,测试成功
May 14 PHP
smarty section简介与用法分析
Oct 03 PHP
Apache实现Web Server负载均衡详解(不考虑Session版)
Jul 05 PHP
php生成图形(Libchart)实例
Nov 06 PHP
php断点续传之如何分割合并文件
Mar 22 PHP
PHP调试函数和日志记录函数分享
Jan 31 PHP
PHP的Socket通信之UDP通信实例
Jul 02 PHP
php获取文章内容第一张图片的方法示例
Jul 03 PHP
PHP简单实现模拟登陆功能示例
Sep 15 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
Nov 16 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
Nov 19 PHP
php实现微信公众平台账号自定义菜单类
Dec 02 #PHP
php获取CSS文件中图片地址并下载到本地的方法
Dec 02 #PHP
PHP间隔一段时间执行代码的方法
Dec 02 #PHP
ThinkPHP采用原生query实现关联查询left join实例
Dec 02 #PHP
php面象对象数据库操作类实例
Dec 02 #PHP
PHP实现的比较完善的购物车类
Dec 02 #PHP
Yii框架关联查询with用法分析
Dec 02 #PHP
You might like
php中关于普通表单多文件上传的处理方法
2011/03/25 PHP
php实现可运算的验证码
2015/11/10 PHP
根据key删除数组中指定的元素实现方法
2017/03/02 PHP
PHP如何搭建百度Ueditor富文本编辑器
2018/09/21 PHP
xtree.js 代码
2007/03/13 Javascript
JavaScript 学习笔记二 字符串拼接
2010/03/28 Javascript
NodeJS学习笔记之(Url,QueryString,Path)模块
2015/01/13 NodeJs
jquery实现可自动收缩的TAB网页选项卡代码
2015/09/06 Javascript
如何使用jquery实现文字上下滚动效果
2016/10/12 Javascript
jQuery动态增减行的实例代码解析(推荐)
2016/12/05 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
重新认识vue之事件阻止冒泡的实现
2018/08/02 Javascript
iconfont的三种使用方式详解
2018/08/05 Javascript
关于React动态加载路由处理的相关问题
2019/01/07 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
2019/02/26 Javascript
JS 创建对象的模式实例小结
2020/04/28 Javascript
vue3.0 上手体验
2020/09/21 Javascript
Python函数中定义参数的四种方式
2014/11/30 Python
Python实现登录接口的示例代码
2017/07/21 Python
Python构建网页爬虫原理分析
2017/12/19 Python
pandas修改DataFrame列名的方法
2018/04/08 Python
对pandas replace函数的使用方法小结
2018/05/18 Python
修复 Django migration 时遇到的问题解决
2018/06/14 Python
对python多线程SSH登录并发脚本详解
2019/02/14 Python
使用Python控制摄像头拍照并发邮件
2019/04/23 Python
使用python自动追踪你的快递(物流推送邮箱)
2020/03/17 Python
Python利用for循环打印星号三角形的案例
2020/04/12 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
2020/05/15 Python
英国和爱尔兰的自炊式豪华度假小屋:Rural Retreats
2018/06/08 全球购物
Yahoo-PHP面试题2
2014/12/06 面试题
经贸日语毕业生自荐信
2013/11/03 职场文书
安全责任协议书
2014/04/21 职场文书
优秀护士先进事迹
2014/05/08 职场文书
四年级学生期末评语
2014/12/26 职场文书
社区文明创建工作总结2015
2015/04/21 职场文书
mysql 乱码 字符集latin1转UTF8
2022/04/19 MySQL