使用php在页面输出时,动态加载合并压缩js

本文旨在解决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));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值