Yii核心组件AssetManager原理分析

本文我们通过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程序设计有所帮助。

(0)

相关推荐

  • 深入浅析yii2-gii自定义模板的方法

    前言: Yii 是什么 Yii 是一个高性能,基于组件的 PHP 框架,用于快速开发现代 Web 应用程序.名字 Yii (读作 `易`)在中文里有 "极致简单与不断演变" 两重含义,也可看作 **Yes It Is**! 的缩写. Yii 最适合做什么? Yii 是一个通用的 Web 编程框架,即可以用于开发各种基于 PHP 的 Web 应用.因为基于组件的框架结构和设计精巧的缓存支持,Yii 特别适合开发大型应用,如门户网站.论坛.内容管理系统(CMS).电子商务项目和 RESTf

  • Yii-自定义删除确认弹框(zyd)jquery实现代码

    1.链接 复制代码 代码如下: <?php echo CHtml::link(Yii::t('cmp','Delete'),'javascript:',array('class'=>'c_06c','onclick'=>'return art_del_confirm("/company/msglog/delete/id/'.$data->zml_id.'","你确定要删除这条消息吗?")'))?> 2.jq 复制代码 代码如下: <

  • Yii结合CKEditor实现图片上传功能

    这几天做的一个项目中需要在所见即所得编辑器中实现图片上传的功能,我因为比较喜欢CKEditor的界面而选择了它.虽然有跟CKEditor配合良好的CKFinder,不过这个东东的功能太复杂,简单看了下CKEdtior的文档,发现这个功能还是可以自己实现而不用借助CKFinder的. 下面代码虽然基于Yii Framework的,但是用其他框架或者语言思路却是完全一样的,有需要的童鞋可以参考一下. 首先要让CkEditor出现图片上传的功能,需要配置编辑器的filebrowserImageUplo

  • yii2.0之GridView自定义按钮和链接用法

    本文实例讲述了yii2.0之GridView自定义按钮和链接用法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <?= GridView::widget([         'dataProvider' => $dataProvider,         //'filterModel' => $searchModel,         'columns' => [             ['class' => 'yii\grid\SerialColumn'

  • yii2高级应用之自定义组件实现全局使用图片上传功能的方法

    本文讲述了yii2高级应用之自定义组件实现全局使用图片上传功能的方法.分享给大家供大家参考,具体如下: 此例为yii2高组应用,这里只提供一个简单的事例 在yii2中,在使用到上传图片时有自带的一个上传图片类,但不太好用. 其中有一种方式,把自己写的一个上传图片类文件,注册成一个组件,在全局中使用.(我记得我在里面有写过一篇小物件的使用) 这里,我只作一个简单的自定义组件介绍 1.在backend(或frontend)定义一个 upload.php(注意路径: backend/component

  • yii2整合百度编辑器umeditor及umeditor图片上传问题的解决办法

    我们接下来就来聊聊Yii2框架是如何整合百度编辑器umeditor的. umeditor是啥,我只听过ueditor,你这umeditor是不是盗版的东东喃?umeditor呢,说白了就是mini版的ueditor,按照百度官方说法,其实就是编辑器中的"短软小",但是功能俱全.咳咳,咱们回归正题. 首先勒,咱们先去官网下载一份mini版的ueditor umeditor,注意哦,是um editor. 下载下来解压放到项目根目录下面的 /css目录下 命名为umeditor,具体位置各

  • YII2.0之Activeform表单组件用法实例

    本文实例讲述了YII2.0之Activeform表单组件用法.分享给大家供大家参考,具体如下: Activeform 文本框:textInput(); 密码框:passwordInput(); 单选框:radio(),radioList(); 复选框:checkbox(),checkboxList(); 下拉框:dropDownList(); 隐藏域:hiddenInput(); 文本域:textarea(['rows'=>3]); 文件上传:fileInput(); 提交按钮:submitBu

  • YII使用url组件美化管理的方法

    本文实例讲述了YII使用url组件美化管理的方法.分享给大家供大家参考,具体如下: urlManager组件 yii的官方文档对此的解释如下: urlSuffix  此规则使用的url后缀,默认使用CurlManger::urlSuffix,值为null.例如可以将此设置为.html,让url看起来"像"是一个静态页面. caseSensitive  是否大小写敏感,默认使用CUrlManager::caseSensitive,值为null. defaultParams  该规则使用的

  • yii实现图片上传及缩略图生成的方法

    本文实例讲述了利用yii框架来实现图片上传功能并在上传成功之后自动生成缩略图的方法,分享给大家供大家参考.具体实现方法如下: Action文件: 复制代码 代码如下: <?php /**  * TestController.php  * Created on: 2014-1-26 12:59:36 by Outsider  */ class TestController extends CController {       /**      * 缩略图片生成      * @ path 图片路

  • yii2中的rules 自定义验证规则详解

    yii2的一个强大之处之一就是他的Form组件,既方便又安全.有些小伙伴感觉用yii一段时间了,好嘛,除了比tp"难懂"好像啥都没有. 领导安排搞一个注册的功能,这家伙刷刷刷的又是百度啥啥啥好的表单样式,又是百度啥啥啥validate验证,真替这家伙捏把汗. 当然啦,废话说在前头,咱们的重点喃,是要利用ActiveForm,然后怎么去实现自定义验证规则. 先来说说场景: 条件:①.有两个字段分别是A和B ②.A有两个值分别是1和2 需求是:当用户选择的A的值等于1的时候,B的值必须填写

  • Yii扩展组件编写方法实例分析

    本文实例讲述了Yii扩展组件编写方法.分享给大家供大家参考.具体如下: 因为Yii本身就引入了Prado的component-based 思想做为主要思想.因此,组件在yii中是很重要的. 组件一般放在components目录里,其格式示例基本如下: <?php /** * some description about the <span style="color: rgb(34, 34, 34); font-family: Arial, sans-serif; font-size:

随机推荐