牛骨文教育服务平台(让学习变的简单)
博文笔记

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

创建时间:2016-04-27 投稿人: 浏览次数:844

本文旨在解决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>
";//输出压缩后的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:wwwhtdocsyuicompressor.jar", 
// "save_path"=>"D:wwwhtdocs
esults\", //必须有可写权限
// // -------- 全局设置 --------- //
// "charset"=>"utf-8", //文件的编码
// "line-break"=>false, //在指定的列后插入一个 line-bread 符号
// // -------- javascript 代码的配置选项 --------- //
// "nomunge"=>false,  //只是简单压缩,清除空行空格注释等。
// "semi"=>false, //保留所有的分号
// "optimizations"=>false, //禁止优化代码.
// ));
// 
// //对单个文件压缩
// $resutlt = $yui->compress("D:wwwhtdocsswfobject_src.js");
// print_r ($resutlt);
// 
// //对目录文件压缩
// $resutlt = $yui->directory("D:wwwhtdocs\");
// 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("
",$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));
    }
}
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。