本文旨在解决php模板中模块化视图加载css样式文件和js样式的问题。
分模块化的php模板中,控制器输出的视图旨在body标签中,而不去关心头部和尾部样式。
这样在模块化视图中加载其所需的样式和js文件位置就成了一个问题。
这个问题可以通过在布局的样式模板中添加js和css替代变量解决,视图中通过统一的方法去加载所需文件。
如果我们想优化页面的加载速度,可以根据压缩css和js文件提高页面的访问速度。同时合并文件又能再提高访问速度。
于是乎,我采用了这用方法来优化脚本文件和访问速度。
1.通过统一的方法将所需加载的文件路径保存
2.在视图将要输出时,合并压缩文件,使用替代文件输出引用。
/*
*添加js文件
* @param $files array js文件地址数组
*/
function add_js_to_view($files)
{
static $default_head_js = array();//定义静态变量存储添加的js文件
$default_head_js = array_merge($default_head_js,$files);//合并已添加的文件
$ci->view_data['default_head_js'] = $default_head_js;//将此静态变量输出到模板中使用(此行为伪代码)
return;
}
/*
* 压缩js文件(同理可处理css文件)
* 此处理过程为:检测配置文件中是否有过这些文件合并的压缩文件,同时检测资源的改变,
*
* 模板中使用 echo compress_js($default_head_js) 输出压缩的文件
* @param $arr array 需要压缩的文件地址数组
*/
function compress_js($arr){
if(!$arr && !is_array($arr)) return ;
$base_url = dirname(BASEPATH).'/static/compress/';//压缩文件存放目录
/*实例化压缩类*/
$yui = new yuicompressor(array(
'java_home'=>'java', //或自己指定 jdk 安装的 bin 目录 (绝对路径)
'jar_file'=>$base_url.'yuicompressor-2.4.8.jar',
'save_path'=>$base_url, //必须有可写权限
// -------- 全局设置 --------- //
'charset'=>'utf-8', //文件的编码
'line-break'=>false, //在指定的列后插入一个 line-bread 符号
// -------- javascript 代码的配置选项 --------- //
'nomunge'=>false, //只是简单压缩,清除空行空格注释等。
'semi'=>false, //保留所有的分号
'optimizations'=>false, //禁止优化代码.
));
$out_name = '';//最终js文件名
$tag_new = true;//是否需要重新合并压缩
if(file_exists($base_url.'config.php')){//检测配置文件是否存在
$content = file_get_contents($base_url.'config.php');
if($content != ''){//检测配置文件里的内容是否为空
$compress_config = json_decode($content,true);
$config_key = '';//此合并文件的key
foreach ($arr as $a){
$config_key .= $a.'_';//拼接key值
}
if(isset($compress_config[$config_key])){//判断此
$tag = false;//记录资源是否有变动
foreach ($arr as $a){
@$filemtime = filemtime($a);//获取文件上传修改时间戳
if($compress_config[$config_key][$a]['time'] != $filemtime){
@unlink($compress_config[$config_key]['compress_name'].'.min.js');//删除无用的文件
unset($compress_config[$config_key]);
$tag = true;//资源有变动,即资源上次更改时间戳有变化
break;
}
}
if($tag && file_exists('/static/compress/'.$compress_config[$config_key]['compress_name'].'.min.js')) {//如果资源无变动,并且文件存在,则使用次文件
$out_name = $compress_config[$config_key]['compress_name'];
$tag_new = false;
}
}
}
}
if($tag_new){
$config_key = '';
$compress_name = 'index_'.time();//编译文件名
$compress_config[$config_key] = array();
foreach ($arr as $a){
$config_key .= $a.'_';
file_put_contents($base_url.$compress_name.'.js',file_get_contents($a).";",FILE_APPEND);//合并所以文件
}
foreach ($arr as $a){
@$compress_config[$config_key][$a]['time'] = filemtime($a);
}
$compress_config[$config_key]['compress_name'] = 'index_'.time();
file_put_contents($base_url.'config.php',json_encode($compress_config));
//对单个文件压缩
$resutlt = $yui->compress($base_url.$compress_name.'.js');
$out_name = $compress_config[$config_key]['compress_name'];
}
echo "<script src='" . base_url('/static/compress/'.$out_name.'.min.js') . "'></script>\r\n";//输出压缩后的js文件引用标签
}
///*
// * 参考此类
//
//
// * PHP YUICompressor Class (Dual licensed under the MIT)
// * 风吟 (http://fengyin.name/guestbook.php)
// * DEMO http://sweet.fengyin.name/ (yui online compressor)
// ----------------------------------------------------------
// 要求: dk 1.4+ php exec()
// 作用: 使用 yuicompressor 批量压缩一个目录的 js 或者 css 文件.也可以对单个文件进行压缩
// ----------------------------------------------------------
//
// //Windows 调用方式:
//
//
//$yui = new yuicompressor(array(
// 'java_home'=>'java', //或自己指定 jdk 安装的 bin 目录 (绝对路径)
// 'jar_file'=>'D:\www\htdocs\yuicompressor.jar',
// 'save_path'=>'D:\www\htdocs\results\\', //必须有可写权限
// // -------- 全局设置 --------- //
// 'charset'=>'utf-8', //文件的编码
// 'line-break'=>false, //在指定的列后插入一个 line-bread 符号
// // -------- javascript 代码的配置选项 --------- //
// 'nomunge'=>false, //只是简单压缩,清除空行空格注释等。
// 'semi'=>false, //保留所有的分号
// 'optimizations'=>false, //禁止优化代码.
// ));
//
// //对单个文件压缩
// $resutlt = $yui->compress('D:\www\htdocs\swfobject_src.js');
// print_r ($resutlt);
//
// //对目录文件压缩
// $resutlt = $yui->directory('D:\www\htdocs\\');
// print_r($resutlt);
//
// ----------------------------------------------------------
//
// //Linux 调用方式:
//
// $yui = new yuicompressor(array(
// 'java_home'=>'java', //或自己指定 jdk 安装的 bin 目录 (绝对路径)
// 'jar_file'=>'/home/admin/yuicompressor-2.4.2.jar',
// 'save_path'=>'/home/admin/results/', //必须有可写权限
// // -------- 全局设置 --------- //
// 'charset'=>'utf-8', //文件的编码
// 'line-break'=>false, //在指定的列后插入一个 line-bread 符号
// // -------- javascript 代码的配置选项 --------- //
// 'nomunge'=>false, //只是简单压缩,清除空行空格注释等。
// 'semi'=>false, //保留所有的分号
// 'optimizations'=>false, //禁止优化代码.
// ));
//
// //对单个文件压缩
// $resutlt = $yui->compress('/home/admin/style.css');
// print_r ($resutlt);
//
// //对目录文件压缩
// $resutlt = $yui->directory('/home/admin/');
// print_r($resutlt);
//
// */
class yuicompressor {
function __construct($options = array()) {
$this->options = $options;
}
function args($o) {
$jsargs = '';
$line_break = '';
$charset = '';
$o['line-break'] && ($line_break = ' --line-break ' . $o['line-break'] . ' ');
$o['charset'] && ($charset = ' --charset ' . $o['charset'] . ' ');
$o['nomunge'] && ($jsargs .= ' --nomunge ');
$o['semi'] && ($jsargs .= ' --preserve-semi ');
$o['optimizations'] && ($jsargs .= ' --disable-optimizations ');
$exten = $this->getExtension($o['file']);
$cmd = array();
$newfile = $o['save_path'] . $this->replace($o['file']);
$cmd['file'] = $newfile;
$cmd['shell'] = $o['java_home'] . ' -jar ' . $o['jar_file'] . ' --type ' . $exten['extension'] . $charset . $line_break . $jsargs . $o['file']. ' > ' . $newfile;
return $cmd;
}
function getExtension($fn) {
return pathinfo(strtolower($fn));
}
function replace($fn) {
$exten = $this->getExtension($fn);
return str_replace('.'.$exten['extension'], '.min.' . $exten['extension'], $exten['basename']);
}
function exec($cmd) {
exec($cmd['shell'].' 2>&1',$out, $status);
return array(
'shell' => $cmd['shell'],
'out' => implode("\n",$out),
'status' => $status,
'success' => $cmd['file']
);
}
function ls($dir) {
!($dh = opendir($dir)) && exit('open directory error');
while (($file = readdir($dh)) !== false) {
$exten = $this->getExtension($file);
if ($exten['extension'] == 'js' || $exten['extension'] == 'css') {
$files[] = $dir . $file;
}
}
closedir($dh);
return $files;
}
function directory($dir) {
!is_dir($dir) && exit('directory error');
foreach ($this->ls($dir) as $file) {
$fn[] = $this->compress($file);
}
return $fn;
}
function compress($file) {
$this->options['file'] = $file;
return $this->exec($this->args($this->options));
}
}