当前位置:王中王鉄算盘开奖结果 > 品牌动态 > 静态资源文件自动压缩并替换成压缩版本

静态资源文件自动压缩并替换成压缩版本

文章作者:品牌动态 上传时间:2019-12-30

静态财富文件自动减削并替换到压缩版本(大型网址优化本领)

2015/11/26 · HTML5 · 静态能源

初藳出处: Kelly   

那贰次,小编总计和共享黄金年代项大型网址优化技巧,那正是在档案的次序中自行裁减静态能源文件(css、js),并让网址活动加载压缩后的财富文件。当然,那项才具在雅虎35条前端优化建议里也会有记载,但它那只是给出一个答辩的方案而已,并且利用的是外界压缩工具去收缩,而在自己的品种中,是直接通过友好的主次自动化去减弱全数css、js文件,然后让页面一直加载所减弱后的能源,接下去直接步向正题。

此番实验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的景况(英特网搭建不论是搭建LAMP照旧LNMP的教程都各种各样混淆黑白,下一次小编会计算和享受什么在LINUX下搭建服务器情况的博文,而且搭建的条件必得贰遍性搭建设成功的)。所选拔的框架是CI框架,所使用的模板是斯Matty模板引擎。当然了,那一个只是本人所利用的条件而已,要是您是PHP开辟者,倘让你要测验下本次试验,那么,小编建议您的PHP版本接受5.4之上,至于框架用怎么着都以能够的。而只要你不是PHP开辟者(你是JSP恐怕是ASP开采者或然是别的开采者),那么你知道好那大器晚成思路后,完全能够在友好深谙的语言里实行试验测验。

一、原理图

先是小编画一张思路图,便于大家先了然。

先是是财富减少原理图:

图片 1

随着是财富文件替换的原理图:

图片 2

一旦大家认真精晓而且看懂这两张原理图的话,基本上也就调控了本身所享受的笔触。假诺照旧无法分晓的话,接下去笔者会结合代码,对以上原理图的每一步实行详尽讲明。

二、思路详细解析

1.先是是调用该滑坡的格局,你能够把该办法放在网址所要加载的公共类的地点,比如每一次访谈网址都会调用该滑坡方法实行减少。当然,这一个只是在开采条件才会每趟都调用,即便是线上的景况,在您的网址发一次新本子的时候,调用贰遍用来生成压缩版的静态能源就能够了。

class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(卡塔尔国; //压缩jscss资源文件 $this->compressResHandle(卡塔尔; } /** * 压缩js、css资源文件(优化) * @return [type] [description] */ private function compressResHandle(State of Qatar { $this->load->library('ResMinifier'State of Qatar; //压缩内定文件夹下的能源文件 $this->resminifier->compressRes(卡塔尔; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library('ResMinifier');
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}

2.接着就调用了 ResMinifier类里的 compressRes方法。在此边小编先附上 ResMinifier这些类的代码,然后方便一步步开展分析解说

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 财富压缩类 */ class ResMinifier { /** 供给减小的财富目录*/ public $compressResDir = ['css', 'js']; /** 忽视压缩的路径,比方此处是js/icon初阶的路子忽视压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 能源根目录*/ public $resRootDir; /** 能源版本文件路径*/ private $resStatePath; public function __construct(State of Qatar { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes(卡塔尔国 { //获取存放版本的能源文件 $resState = $this->getResState(State of Qatar; $count = 0; //开首遍历必要收缩的能源目录 foreach ($this->compressResDir as $resDir卡塔尔(قطر‎ { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS卡塔尔国State of Qatar as $fileState of Qatar { //获取该能源文件的绝对路线$filePath = str_replace('\', '/', $file->getRealPath(卡塔尔卡塔尔国; //获取文件相对路线 $object = substr($filePath, strlen($this->resRootDir卡塔尔State of Qatar; //计算文件的版本号 $state = $this->_getResStateVersion($filePath卡塔尔; //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension卡塔尔State of Qatar { continue; } //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p判定是最要害部分之大器晚成*****************// //剖断文件是或不是留存且早就更动过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePathState of QatarState of Qatar { continue; } //确认保障/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); } $resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState卡塔尔国; } public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension卡塔尔 { //获取财富相对路线 $filePath = $this->resRootDir . $object; //剖断能源是或不是留存 if (!file_exists($filePath卡塔尔国卡塔尔(قطر‎ return "财富文件不设有{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath卡塔尔国; //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSION卡塔尔(قطر‎; //是还是不是要减削 $needCompress = true; //判定财富文件是或不是是以 .min.css只怕.min.js结尾的 //此类结尾经常都是已回降过,举个例子jquery.min.js,就不要再压缩了 if (str_end_with($object, '.min.'.$extension, true卡塔尔卡塔尔 { //压缩后的能源寄放路线,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($objectState of Qatar - strlen($extension卡塔尔国 - 4卡塔尔(قطر‎ . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDirState of QatarState of Qatar { //此处是亟需减小的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔(قطر‎ - strlen($extension卡塔尔State of Qatar . $state . '.' . $extension; //看看是还是不是是忽视的路径前缀 foreach ($this->compressResIngorePrefix as $v卡塔尔 { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; } /** * 获取贮存能源版本的文书 * 它是坐落于三个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; } /** * 总计文件的本子号,那几个是依据测算文件MD5散列值得到版本号 * 只要文件内容改变了,所总结得到的散列值就能够不等同 * 用于剖断财富文件是不是有退换过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); } /** * 确认保障目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } } /** * 将核减后的能源文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}退步"卡塔尔国; show_error("写入文件{$minFilePath}退步", -1卡塔尔国; } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不扶持压缩{extension}文件[$filePath]"); show_error("不扶助压缩{extension}文件[$filePath]", -1); } } private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $contentState of Qatar; } } 点击打开能源压缩类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 资源压缩类
*/
class ResMinifier {
    /** 需要压缩的资源目录*/
    public $compressResDir = ['css', 'js'];
    /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
    public $compressResIngorePrefix = ['js/icon'];
    /** 资源根目录*/
    public $resRootDir;
    /** 资源版本文件路径*/
    private $resStatePath;
 
    public function __construct() {
        $this->resRootDir = WEBROOT . 'www/';
        $this->resStatePath = WEBROOT . 'www/resState.php';
    }
 
    public function compressRes() {
        //获取存放版本的资源文件
        $resState = $this->getResState();
        $count = 0;
 
        //开始遍历需要压缩的资源目录
        foreach ($this->compressResDir as $resDir) {
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                //获取该资源文件的绝对路径
                $filePath = str_replace('\', '/', $file->getRealPath());
                //获取文件相对路径
                $object = substr($filePath, strlen($this->resRootDir));
                //计算文件的版本号
                $state = $this->_getResStateVersion($filePath);
 
                //获取文件的几个参数值
                if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                    continue;
                }
 
                //压缩文件的绝对路径
                $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
 
                //************此处p判断是最重要部分之一*****************//
                //判断文件是否存在且已经改动过
                if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                    continue;
                }
 
                //确保/www/min/目录可写
                $this->_ensureWritableDir(dirname($minFilePath));
 
                if ($needCompress) {
                    $this->compressResFileAndSave($filePath, $minFilePath);
                } else {
                    copy($filePath, $minFilePath);
                }
 
                $resState[$object] = $state;
                $resState[$minObject] = '';
                $count++;
 
                if ($count == 50) {
                    $this->_saveResState($resState);
                    $count = 0;
                }
 
            }
        }
        if($count) $this->_saveResState($resState);
    }
 
    public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
        //获取资源绝对路径
        $filePath = $this->resRootDir . $object;
        //判断资源是否存在
        if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
        //版本号
        $state = $this-> _getResStateVersion($filePath);
        //文件名后缀
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        //是否要压缩
        $needCompress = true;
 
        //判断资源文件是否是以 .min.css或者.min.js结尾的
        //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
        if (str_end_with($object, '.min.'.$extension, true)) {
            //压缩后的资源存放路径,放在 /www/min/ 目录下
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
            $needCompress = false;
        } else if (in_array($extension, $this->compressResDir)) {
            //此处是需要压缩的文件目录
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
            //看看是否是忽略的路径前缀
            foreach ($this->compressResIngorePrefix as $v) {
                if (str_start_with($object, $v, true)) {
                    $needCompress = false;
                }
            }
        } else {
            $minObject = 'min/'.$object;
            $needCompress = false;
        }
        return true;
    }
 
    /**
     * 获取存放资源版本的文件
     * 它是放在一个数组里
     * $resState = array(
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *     );
     * @return [type] [description]
     */
    public function getResState() {
        if (file_exists($this->resStatePath)) {
            require $this->resStatePath;
            return $resState;
        }
        return [];
    }
 
    /**
     * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
     * 只要文件内容改变了,所计算得到的散列值就会不一样
     * 用于判断资源文件是否有改动过
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    public function _getResStateVersion($filePath) {
        return base_convert(crc32(md5_file($filePath)), 10, 36);
    }
 
    /**
     * 确保目录可写
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    private function _ensureWritableDir($dir) {
        if (!file_exists($dir)) {
            @mkdir($dir, 0777, true);
            @chmod($dir, 0777);
        } else if (!is_writable($dir)) {
            @chmod($dir, 0777);
            if (!is_writable($dir)) {
                show_error('目录'.$dir.'不可写');
            }
        }
    }
 
    /**
     * 将压缩后的资源文件写入到/www/min/下去
     * @param  [type] $filePath    [description]
     * @param  [type] $minFilePath [description]
     * @return [type]              [description]
     */
    private function compressResFileAndSave($filePath, $minFilePath) {
        if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
 
            //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
            show_error("写入文件{$minFilePath}失败", -1);
        }
    }
 
    /**
     * 压缩资源文件
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    private function compressResFile($filePath) {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if ($extension === 'js') {
            require_once 'JShrink/Minifier.php';
            return JShrinkMinifier::minify(file_get_contents($filePath));
        } else if ($extension ==='css') {
            $content = file_get_contents($filePath);
            $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
            $content = str_replace(["rn", "r", "n"], '', $content);
            $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
            $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
            $content = str_replace(';}', '}', $content);
            return $content;
        } else {
            //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
            show_error("不支持压缩{extension}文件[$filePath]", -1);
 
        }
    }
 
    private function _saveResState($resState) {
        ksort($resState);
        $content = "<?phpnn$resState = array(n";
        foreach ($resState as $k => $v) {
            $content .= "t '$k' => '$v',n";
        }
        $content .= ");nn";
        file_put_contents($this->resStatePath, $content);
    }
 
}
 
点击打开 资源压缩类

生龙活虎体类半数以上代码笔者都加了批注,方便大家快速通晓。这里笔者也会对每大器晚成行代码进行解释。

(1)

PHP

/** 要求减小的财富目录*/ public $compressResDir = ['css', 'js']; /** 忽视压缩的路线,比如此处是js/icon起首的门径忽视压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 能源根目录*/ public $resRootDir; /** 能源版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; }

1
2
3
4
5
6
7
8
9
10
11
12
13
/** 需要压缩的资源目录*/
    public $compressResDir = ['css', 'js'];
    /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
    public $compressResIngorePrefix = ['js/icon'];
    /** 资源根目录*/
    public $resRootDir;
    /** 资源版本文件路径*/
    private $resStatePath;
 
    public function __construct() {
        $this->resRootDir = WEBROOT . 'www/';
        $this->resStatePath = WEBROOT . 'www/resState.php';
    }

$compressResDir变量是亟需减少的能源目录,倘令你有新的管理目录,能够在这里变量里纵然新的目录名就可以管理。附上自个儿测量试验项目标目录图

图片 3

$compressResIngorePrefix 忽视被减弱的门路的渠道前有的是该数组变量的字符串,譬喻有三个能源路线为 js/icon/bg.js可能是js/icon_index.js或然是js/icon.header.js,假诺在该数组中投入了 js/icon那个字符串,那么财富路线为js/icon开始的都会被忽视掉,也便是一直跳过,不用压缩。(因为财富文件里总有一点是没有须要减小的嘛)

$resRootDir存放能源根目录的

$resStatePath 那几个是财富版本文件路线

(2)步向compressRes(卡塔尔国 方法,大家先分析后边那少年老成段代码

PHP

public function compressRes(卡塔尔(قطر‎ { //获取贮存版本的财富文件 $resState = $this->getResState(卡塔尔国; $count = 0;

1
2
3
4
public function compressRes() {
        //获取存放版本的资源文件
        $resState = $this->getResState();
        $count = 0;

——————————-调用getResState() 讲解start————————————————————-

此处首先是调用 $this->getResState(State of Qatar 方法来获得寄放版本的资源文件,此处先跳到该方法看看是怎么着写的,其实正是带有该公文,然后回到里面寄放版本号的数组,大家看注释可以清楚该公文里贮存版本号的格式(顺便附上航海用体育场地让我们看看)

PHP

/** * 获取寄放财富版本的文书 * 它是献身多少个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
     * 获取存放资源版本的文件
     * 它是放在一个数组里
     * $resState = array(
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *     );
     * @return [type] [description]
     */
    public function getResState() {
        if (file_exists($this->resStatePath)) {
            require $this->resStatePath;
            return $resState;
        }
        return [];
    }

(财富版本文件截图:)

图片 4

——————————-调用getResState() 讲解end————————————————————-

随后看compressRes(卡塔尔(قطر‎里的那豆蔻梢头段代码

PHP

//起头遍历须要减小的能源目录 foreach ($this->compressResDir as $resDir卡塔尔国 { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTSState of Qatar卡塔尔 as $file卡塔尔 { //获取该财富文件的相对路径$file帕特h = str_replace('\', '/', $file->getRealPath(卡塔尔国卡塔尔国; //获取文件相对路线 $object = substr($file帕特h, strlen($this->resRootDirState of QatarState of Qatar; //总结文件的本子号 $state = $this->_getResStateVersion($filePath);

1
2
3
4
5
6
7
8
9
//开始遍历需要压缩的资源目录
        foreach ($this->compressResDir as $resDir) {
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                //获取该资源文件的绝对路径
                $filePath = str_replace('\', '/', $file->getRealPath());
                //获取文件相对路径
                $object = substr($filePath, strlen($this->resRootDir));
                //计算文件的版本号
                $state = $this->_getResStateVersion($filePath);

首先个遍历的是js和css目录 第一个遍历是将js目录大概css目录里的文本都改成路线方式,

举个例子获取文件的相对路线 $filePath 的值是那样子的:

/usr/local/apache2/htdocs/project/www/css/home/index.css

而文件的相对路线$object是那样子的 :

css/home/index.css

这里就开端调用$this->_getResStateVersion($filePath卡塔尔(قطر‎来总计文件的本子号

——————————-调用_getResStateVersion($filePath) 讲解start————————————————————

PHP

/** * 总计文件的版本号,这一个是依赖测算文件MD5散列值获得版本号 * 只要文件内容改换了,所计算得到的散列值就能够不相像 * 用于推断财富文件是或不是有改观过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); }

1
2
3
4
5
6
7
8
9
10
/**
     * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
     * 只要文件内容改变了,所计算得到的散列值就会不一样
     * 用于判断资源文件是否有改动过
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    public function _getResStateVersion($filePath) {
        return base_convert(crc32(md5_file($filePath)), 10, 36);
    }

——————————-调用_getResStateVersion($filePath) 讲解end————————————————————-

大概到版本号后,再看下大器晚成段代码,这里初步调用$this->getObjectInfo(State of Qatar方法,这里收获到压缩文件的相对路线$minObject,是不是须要压缩$needCompress,版本号$state,文件后缀$extension。

PHP

//获取文件的几个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; }

1
2
3
4
//获取文件的几个参数值
                if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                    continue;
                }

——————————调用$this->getObjectInfo() 讲解start————————————————————

PHP

/** * 获取能源文件有关音信 * @param [type] $object 能源文件路线(www/css/home/index.css卡塔尔(قطر‎ * @param [type] $minObject 压缩能源文件路线(www/min/css/home/index.ae123a.css卡塔尔(قطر‎ * @param [type] $needCompress 是不是需求压缩 * @param [type] $state 文件版本号 * @param [type] $extension 文件名后缀 * @return [type] [description] */ public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extensionState of Qatar { //获取能源相对路线 $filePath = $this->resRootDir . $object; //推断能源是或不是存在 if (!file_exists($file帕特h卡塔尔国卡塔尔(قطر‎ return "财富文件不真实{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath卡塔尔; //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSION卡塔尔(قطر‎; //是还是不是要减削 $needCompress = true; //推断财富文件是还是不是是以 .min.css也许.min.js结尾的 //此类结尾日常都是已回退过,举个例子jquery.min.js,就不要再压缩了 if (str_end_with($object, '.min.'.$extension, true卡塔尔(قطر‎State of Qatar { //压缩后的财富贮存路线,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔国 - strlen($extension卡塔尔国 - 4卡塔尔 . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir卡塔尔(قطر‎卡塔尔 { //此处是亟需减弱的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔国 - strlen($extension卡塔尔State of Qatar . $state . '.' . $extension; //看看是或不是是忽视的渠道前缀 foreach ($this->compressResIngorePrefix as $vState of Qatar { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
     * 获取资源文件相关信息
     * @param  [type] $object       资源文件路径 (www/css/home/index.css)
     * @param  [type] $minObject    压缩资源文件路径 (www/min/css/home/index.ae123a.css)
     * @param  [type] $needCompress 是否需要压缩
     * @param  [type] $state        文件版本号
     * @param  [type] $extension    文件名后缀
     * @return [type]               [description]
     */
    public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
        //获取资源绝对路径
        $filePath = $this->resRootDir . $object;
        //判断资源是否存在
        if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
        //版本号
        $state = $this-> _getResStateVersion($filePath);
        //文件名后缀
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        //是否要压缩
        $needCompress = true;
 
        //判断资源文件是否是以 .min.css或者.min.js结尾的
        //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
        if (str_end_with($object, '.min.'.$extension, true)) {
            //压缩后的资源存放路径,放在 /www/min/ 目录下
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
            $needCompress = false;
        } else if (in_array($extension, $this->compressResDir)) {
            //此处是需要压缩的文件目录
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
            //看看是否是忽略的路径前缀
            foreach ($this->compressResIngorePrefix as $v) {
                if (str_start_with($object, $v, true)) {
                    $needCompress = false;
                }
            }
        } else {
            $minObject = 'min/'.$object;
            $needCompress = false;
        }
        return true;
    }

那些措施里的每大器晚成行代码基本上都有注释了,所以就不一句句实行批注了,这里最首要看下边包车型地铁剖断部分:

if (str_end_with($object, ‘.min.’.$extension, true卡塔尔国State of Qatar那么些论断是比较财富文件路径字串后面部分是不是以 .min.$extension 结尾,举例是 jquery.min.js,这种文件本来正是
缩短过的文本,所以就绝不再扩充减少管理了, $minObject 那一个变量寄放的是减掉后的财富文件路线。
此地附上str_end_with(卡塔尔(قطر‎函数的代码:

PHP

/** * 决断 subject 是不是以 search结尾, 参数内定是不是忽视大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_end_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len2 > $len1) return false; if ($ignore_case) { return 0 === strcmp(substr($subject, $len1 - $len2), $search); } else { return 0 === strcasecmp(substr($subject, $len1 - $len2), $search); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
     * 判断 subject 是否以 search结尾, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_end_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len2 > $len1) return false;
        if ($ignore_case) {
            return 0 === strcmp(substr($subject, $len1 - $len2), $search);
        } else {
            return 0 === strcasecmp(substr($subject, $len1 - $len2), $search);
        }
    }

if (in_array($extension, $this->compressResDir卡塔尔国,这几个推断正是是或不是是要求管理的四个目录里的。

然后中间的foreach ($this->compressResIngorePrefix as $vState of Qatar { if (str_start_with($object, $v, true)) { $needCompress = false; } }

这一个是判定是不是是以$this->compressResIngorePrefix属性定义的前尾部分字串早先的路线,是的话就大意压缩该财富文件。

认清到最终else 正是注明该财富文件不须要减小了,最终是回到$minObject,$needCompress,$state,$extension那多少个变量。

——————————-调用$this->getObjectInfo() 讲解end————————————————————-

到此处三翻五次回来看 compressRes(卡塔尔国方法里面包车型大巴代码

PHP

//压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p决断是最要紧片段之生龙活虎*****************// //剖断文件是或不是存在且已经济体改动过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) { continue; }

1
2
3
4
5
6
7
8
//压缩文件的绝对路径
                $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
 
                //************此处p判断是最重要部分之一*****************//
                //判断文件是否存在且已经改动过
                if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                    continue;
                }

这段代码首先是拼接出压缩文件的相对路线,

接着上面那么些判别是重中之重的风流浪漫部分,通过这几个剖断即可领略该能源文件是不是被更动过,即便校订进的话,就再一次对该财富文件实行减少,假诺没改动过,就波路壮阔管理下二个资源文件。看这里的论断:isset($resState[$object]) && $resState[$object] == $state,那个推断正是判别该公文路线是还是不是留存  而且文件中对应的版本号和计算出的版本号是或不是还同样;isset($resState[$minObject]) &&file_exists($minFilePath卡塔尔国,那么些是决断压缩文件路线是否留存,而且该压缩文件是还是不是真实存在目录中。

看下黄金时代段代码,倘诺能走到那大器晚成有的,表达当前的这一个能源文件是被改成过的(代码改善过),那么那时就对文本举办压缩操作了

PHP

//确定保障/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); }

1
2
3
4
5
6
7
8
//确保/www/min/目录可写
                $this->_ensureWritableDir(dirname($minFilePath));
 
                if ($needCompress) {
                    $this->compressResFileAndSave($filePath, $minFilePath);
                } else {
                    copy($filePath, $minFilePath);
                }

$this->_ensureWritableDir(卡塔尔(قطر‎,此措施是要承保新创立的www/min目录是可写的,这里附上代码:

——————————-调用$this->_ensureWritableDir() 讲解start————————————————————-

PHP

/** * 确认保证目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
     * 确保目录可写
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    private function _ensureWritableDir($dir) {
        if (!file_exists($dir)) {
            @mkdir($dir, 0777, true);
            @chmod($dir, 0777);
        } else if (!is_writable($dir)) {
            @chmod($dir, 0777);
            if (!is_writable($dir)) {
                show_error('目录'.$dir.'不可写');
            }
        }
    }

——————————-调用$this->_ensureWritableDir() 讲解end————————————————————-

if ($needCompressState of Qatar,那些剖断财富文件是还是不是需求减小,供给的话调用$this->compressResFileAndSave($filePath, $minFilePath卡塔尔国;无需的话,直接复制文件到压缩文件路线 copy($file帕特h, $minFilePath);

先看$this->compressResFileAndSave()

——————————-调用$this->compressResFileAndSave() 讲解start————————————————————-

PHP

/** * 将裁减后的财富文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}失利"卡塔尔(قطر‎; show_error("写入文件{$minFilePath}失利", -1卡塔尔国; } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不援助压缩{extension}文件[$filePath]"); show_error("不帮助压缩{extension}文件[$filePath]", -1); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
     * 将压缩后的资源文件写入到/www/min/下去
     * @param  [type] $filePath    [description]
     * @param  [type] $minFilePath [description]
     * @return [type]              [description]
     */
    private function compressResFileAndSave($filePath, $minFilePath) {
        if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
 
            //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
            show_error("写入文件{$minFilePath}失败", -1);
        }
    }
 
    /**
     * 压缩资源文件
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    private function compressResFile($filePath) {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if ($extension === 'js') {
            require_once 'JShrink/Minifier.php';
            return JShrinkMinifier::minify(file_get_contents($filePath));
        } else if ($extension ==='css') {
            $content = file_get_contents($filePath);
            $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
            $content = str_replace(["rn", "r", "n"], '', $content);
            $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
            $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
            $content = str_replace(';}', '}', $content);
            return $content;
        } else {
            //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
            show_error("不支持压缩{extension}文件[$filePath]", -1);
 
        }
    }

先减少,再将削减后的从头到尾的经过写入到 压缩文件路线里去。

大家先看下那一个压缩方法:

$this->compressResFile($filePath卡塔尔国; 此方法中分两类压缩,第少年老成类时对js文件举行裁减,第二类的对css文件进行压缩。先说js压缩,这里是调用叁个JShrink的类,它

八个用来压缩js文件的PHP类,百度可以找到,调用这几个类的minify(卡塔尔那几个情势就足以减弱了;而css的滑坡利用正则替换到裁减,把那些空格换行什么的都去掉。到此就减少成功

了,然后再将回退后的财富写入到相应的压缩文件路线里去。

——————————-调用$this->compressResFileAndSave() 讲解end————————————————————-

随着继续看compressRes(卡塔尔(قطر‎那个主意里的代码,这里初步便是保存新的版本号到$resState数组里 $object=>$state,还应该有正是新的裁减路线$minObject,而那边$count++的机能是,当那几个轮回肆拾八遍就将 $resState这一个数组写入贰次到 resState.php文件里,这里是由于严谨考虑而已,假令你不加这一个$count的处理那大器晚成部分也足以,最终写入叁遍就可以了。

PHP

$resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState);

1
2
3
4
5
6
7
8
9
10
11
12
$resState[$object] = $state;
                $resState[$minObject] = '';
                $count++;
 
                if ($count == 50) {
                    $this->_saveResState($resState);
                    $count = 0;
                }
 
            }
        }
        if($count) $this->_saveResState($resState);

这里看$this->_saveResState($resStateState of Qatar,那几个法子便是将$resState数组写入到resState.php文件里去的艺术。

——————————-调用$this->_saveResState($resState) 讲解start————————————————————-

PHP

private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); }

1
2
3
4
5
6
7
8
9
private function _saveResState($resState) {
        ksort($resState);
        $content = "<?phpnn$resState = array(n";
        foreach ($resState as $k => $v) {
            $content .= "t '$k' => '$v',n";
        }
        $content .= ");nn";
        file_put_contents($this->resStatePath, $content);
    }

——————————-调用$this->_saveResState($resState) 讲解end————————————————————-

管理完后,看看所生成的文件,这里一个文本会有三个本子,旧版本并未有去除掉,在支付情形下删不删除都没难点,这里为何不删除旧版本的压缩文件,那就事关到在创新多少个应用服务器代码时所要注意的主题素材里。在这里笔者就多疏解一点呢,轻易地比如吗,日常大型项目中的静态财富和模板文件是布署在不一致的机械集群上的,上线的长河中,静态财富和页面文件的配备时间间隔可能会非凡长,对于一个重型互连网使用来讲纵然在三个超级小的时间间隔内,都有望出现新顾客访谈,假设旧版本的静态财富删除了,但新本子的静态财富还未有安插到位,那么客户就加载不到该静态能源,结果总的来说,所以,日常景观下我们会保留旧版本的静态能源,然后等富有片段构造形成了,再经过一定的脚本删除掉也没涉及,其实,那几个不必删除也是足以的,你思索,叁个门类发三回版本,才会调用一遍财富文件收缩方法,它只会对修改过的文本举行生成新版本号的静态文件而已。那一个就看个人的做法了。

图片 5

小编们可以张开看看,上边这些就是收缩后的公文的代码了,文件原大小为16K,压缩后大致少了5K,现在是11K,压缩比大约是2/3,假使在大型项目中,多个复杂点的页面会有超大的静态财富文件要加载,通过此方法,大大地巩固了加载的快慢。(也许有个别朋友以为压缩个几K也许十几K算什么,完全能够忽视,其实作者想说的是,当您在大型项目中优化项指标时候,能够裁减几K的代码,也给网址的性质提升了第一次全国代表大会截)

图片 6

到此,资源收缩管理就解析完成了。其实,有自然幼功的意中人,能够一贯看自个儿分享的不行代码即可了,假若精通不了,再看自己上边这一步步的拆解解析教学,笔者是处于能看过来此博客的爱人,无论本领是好依旧是稍弱,都能看懂,所以才对代码一步步地张开剖判讲明。(希望各位不吝指教二哥)

————————————————————————————————————————-

  1. 接下去正是教课怎么样替换压缩后的能源文件了。

这个到Home.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Home extends MY_Controller { public function index() { $this->smartyData['test'] = 111; //这些暗中同意是加载 www/css/home/index.css文件 $this->addResLink('index.css'卡塔尔(قطر‎; //那么些暗中认可是加载www/js/jquery.all.min.js文件 $this->addResLink('/jquery.all.min.js'State of Qatar; //那几个暗中认可是加载www/js/index.js文件 $this->addResLink('index.js'卡塔尔(قطر‎; $this->displayView('home/index.tpl'卡塔尔(قطر‎; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Home extends MY_Controller {
    public function index() {
        $this->smartyData['test'] = 111;
        //这个默认是加载 www/css/home/index.css文件
        $this->addResLink('index.css');
        //这个默认是加载www/js/jquery.all.min.js文件
        $this->addResLink('/jquery.all.min.js');
        //这个默认是加载www/js/index.js文件
        $this->addResLink('index.js');
        $this->displayView('home/index.tpl');
    }
}

上边有加载八个能源文件,我们先看看$this->addResLink(卡塔尔(قطر‎;那个方法,这些方法放在My_Controller.php里:

PHP

/** * 能源路线 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
     * 资源路径
     * @param [type] $filePath [description]
     */
    protected function addResLink($filePath) {
        list($filePath, $query) = explode('?', $filePath . '?');
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        foreach ($this->_resLink as $v) {
            if (false === array_search($filePath, $this->_resLink[$extension])) {
                $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
            }
        }
 
        return $this;
    }

此处根本是推断了财富文件是css依然js,然后将其贮存在 $this->_resLink那一个天性里。

那正是说这里作者就先附上My_Controller.php这些父类的全体代码吧

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(卡塔尔(قطر‎; //压缩jscss财富文件 $this->compressResHandle(State of Qatar; } //==========================使用SMARTY模板引擎================================// /* 斯Matty母版页文件路线 */ protected $masterPage = 'default.tpl'; /* 视图像和文字件路径*/ protected $smartyView; /* 要赋值给smarty视图的数码*/ protected $smartyData = []; /* 财富文件*/ protected $_resLink = ['js'=>[], 'css'=>[]]; /** * 使用母版页输出贰个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = nullState of Qatar { //为空则接受私下认可母版 if ($masterPage == null卡塔尔国 $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v卡塔尔; } //内容部分 $output .= $viewContent; //尾巴部分增多js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v卡塔尔国; } //发送最后输出结果以至服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DIKoleos.'斯玛特y.class.php'; $this->smarty = new 斯玛特y(State of Qatar; $this->smarty->setCompileDir(应用软件PATH . 'cache/'卡塔尔国; $this->smarty->setCacheDir(应用软件PATH . 'cache/'State of Qatar; } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } } /** * 能源路径 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; } private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) { if ('/' === $viewName[0]卡塔尔国 $viewName = substr($viewName, 1State of Qatar; //是不是利用模板,有,则路由到 /views/master_page/*****.tpl下去 if ($masterPage) { $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage卡塔尔国; } //是不是设置模板目录 if ($setTemplateDir卡塔尔国 { $templateDir = VIEWPATH; $this->smarty->setTemplateDir($templateDir卡塔尔; } } /** * 压缩js、css资源文件(优化) * @return [type] [description] */ private function compressResHandle(State of Qatar { $this->load->library('Res迷你fier'卡塔尔国; //压缩内定文件夹下的财富文件 $this->resminifier->compressRes(State of Qatar; } } 点击张开 My_Controller.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
 
    //==========================使用SMARTY模板引擎================================//
    /* Smarty母版页文件路径 */
    protected $masterPage = 'default.tpl';
    /* 视图文件路径*/
    protected $smartyView;
    /* 要赋值给smarty视图的数据*/
    protected $smartyData = [];
    /* 资源文件*/
    protected $_resLink = ['js'=>[], 'css'=>[]];
 
    /**
     * 使用母版页输出一个视图
     * @return [type] [description]
     */
    protected function displayView($viewName = null, $masterPage = null) {
        //为空则选用默认母版
        if ($masterPage == null) $masterPage = $this->masterPage;
        //获取视图的输出内容
        $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage);
 
        $output = '';
 
        //添加css Link
        foreach ($this->_resLink['css'] as $v) {
            $output .= res_link($v);
        }
 
        //内容部分
        $output .= $viewContent;
        //尾部添加js 链接
        foreach ($this->_resLink['js'] as $v) {
            $output .= res_link($v);
        }
        //发送最终输出结果以及服务器的 HTTP 头到浏览器
 
        $this->output->_display($output);
        return $output;
    }
 
    private function _fetchView($smartyData, &$viewName, &$masterPage) {
        if ($viewName == null) $viewName = $this->smartyView;
 
        if (empty($this->smarty)) {
            require_once SMARTY_DIR.'Smarty.class.php';
            $this->smarty = new Smarty();
            $this->smarty->setCompileDir(APPPATH . 'cache/');
            $this->smarty->setCacheDir(APPPATH . 'cache/');
        }
 
        //设置视图真实路径
        $this->_getViewDir(true, $viewName, $masterPage, $templateDir);
 
        foreach ($smartyData as $k => $v) {
            $this->smarty->assign($k, $v);
        }
 
        if (empty($masterPage)) {
            return $this->smarty->fetch($viewName);
        } else {
            $this->smarty->assign('VIEW_MAIN', $viewName);
            return $this->smarty->fetch($masterPage);
        }
    }
 
    /**
     * 资源路径
     * @param [type] $filePath [description]
     */
    protected function addResLink($filePath) {
        list($filePath, $query) = explode('?', $filePath . '?');
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        foreach ($this->_resLink as $v) {
            if (false === array_search($filePath, $this->_resLink[$extension])) {
                $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
            }
        }
 
        return $this;
    }
 
    private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) {
        if ('/' === $viewName[0]) $viewName = substr($viewName, 1);
 
        //是否使用模板,有,则路由到 /views/master_page/*****.tpl下去
        if ($masterPage) {
            $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage);
        }
 
        //是否设置模板目录
        if ($setTemplateDir) {
            $templateDir = VIEWPATH;
            $this->smarty->setTemplateDir($templateDir);
        }
    }
 
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library('ResMinifier');
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}
 
点击打开 My_Controller.php

打字与印刷出来 $this->_resLink这么些本性的布局是那样子的:

PHP

Array ( [js] => Array ( [0] => /jquery.all.min.js [1] => index.js ) [css] => Array ( [0] => index.css ) )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Array
(
    [js] => Array
        (
            [0] => /jquery.all.min.js
            [1] => index.js
        )
 
    [css] => Array
        (
            [0] => index.css
        )
 
)

再回到Home.php里面调用 $this->displayView(‘home/index.tpl’State of Qatar;

作者们看这几个办法:

PHP

/** * 使用母版页输出八个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null卡塔尔(قطر‎ { //为空则选拔暗中认可母版 if ($masterPage == nullState of Qatar $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v卡塔尔(قطر‎; } //内容部分 $output .= $viewContent; //尾巴部分增多js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v卡塔尔国; } //发送最后输出结果以至服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DI讴歌MDX.'斯马特y.class.php'; $this->smarty = new 斯Matty(卡塔尔; $this->smarty->setCompileDir(APPPATH . 'cache/'State of Qatar; $this->smarty->setCacheDir(应用软件PATH . 'cache/'State of Qatar; } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
     * 使用母版页输出一个视图
     * @return [type] [description]
     */
    protected function displayView($viewName = null, $masterPage = null) {
        //为空则选用默认母版
        if ($masterPage == null) $masterPage = $this->masterPage;
        //获取视图的输出内容
        $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage);
 
        $output = '';
 
        //添加css Link
        foreach ($this->_resLink['css'] as $v) {
            $output .= res_link($v);
        }
 
        //内容部分
        $output .= $viewContent;
        //尾部添加js 链接
        foreach ($this->_resLink['js'] as $v) {
            $output .= res_link($v);
        }
        //发送最终输出结果以及服务器的 HTTP 头到浏览器
 
        $this->output->_display($output);
        return $output;
    }
 
    private function _fetchView($smartyData, &$viewName, &$masterPage) {
        if ($viewName == null) $viewName = $this->smartyView;
 
        if (empty($this->smarty)) {
            require_once SMARTY_DIR.'Smarty.class.php';
            $this->smarty = new Smarty();
            $this->smarty->setCompileDir(APPPATH . 'cache/');
            $this->smarty->setCacheDir(APPPATH . 'cache/');
        }
 
        //设置视图真实路径
        $this->_getViewDir(true, $viewName, $masterPage, $templateDir);
 
        foreach ($smartyData as $k => $v) {
            $this->smarty->assign($k, $v);
        }
 
        if (empty($masterPage)) {
            return $this->smarty->fetch($viewName);
        } else {
            $this->smarty->assign('VIEW_MAIN', $viewName);
            return $this->smarty->fetch($masterPage);
        }
    }

那生龙活虎段代码未有风度翩翩部分正是调用了Smarty模板引擎的源委,那几个关于斯Matty的文化小编就不讲了,大家能够和睦百度,这里主要讲 res_link(卡塔尔国那几个函数,正是经过那个函数来进展能源文件替换的。先看这几个函数的代码:

PHP

/** * 输出 HttpHead 中的财富总是。 css/js 自动推断真实路线 * @param string 文件路线 * @return string */ function res_link($file) { $file = res_path($file, $extension); if ($extension === 'css') { return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>'; } else if ($extension === 'js') { return '<script type="text/javascript" src="'.$file.'"></script>'; } else { return false; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
     * 输出 HttpHead 中的资源连接。 css/js 自动判断真实路径
     * @param  string  文件路径
     * @return string      
     */
    function res_link($file) {
        $file = res_path($file, $extension);
 
        if ($extension === 'css') {
           return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>';
        } else if ($extension === 'js') {
            return '<script type="text/javascript" src="'.$file.'"></script>';
        } else {
            return false;
        }
    }

这里最关键就是 res_path(State of Qatar 函数了,那么些函数能活动路由能源的真人真事路径。比方:index.css = > css/home/index.css

该函数最根本的二个职能是替换财富的压缩版本。

一贯看代码:

PHP

/** * 智能路由能源实际路线 * @param string 路径 * @param string 扩展名 * @return string 真实路线 */ function res_path($file, &$extension卡塔尔 { //检查是还是不是留存询问字符串 list($file, $query卡塔尔国 = explode('?', $file . '?'卡塔尔; //拿到扩充名 $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); // $file = str_replace('\', '/', $fileState of Qatar; //取稳当前调控器名 global $class; if ($class == null卡塔尔(قطر‎ exit('can not get class name'卡塔尔; $className = strtolower($class卡塔尔; //此处的规行矩步是那般: //举例,假设不加 / ,Home调控器对应的格式是: index.css,那么 此处的路线会造成css/home/index.css //就算有 / ,调整器的格式能够是 /main.css,那么这里的路线会变成 css/main.css(公用的css类) if ('/' !== $file[0]卡塔尔 { //index.css => css/home/index.css $object = $extension .'/'. $className .'/' . $file; } else { // /css/main.css 或许 /main.css => css/main.css $object = substr($file, 1卡塔尔; //若object是 main.css ,则自动抬高 扩大名目录 => css/main.css if (0 !== strncasecmp($extension, $object, strlen($extension卡塔尔国卡塔尔国卡塔尔 { $object = $extension . '/' . $object; } } //能源真实路线 $filepath = WEBROOT.'www/'.$object; //替换压缩版本,那有个别逻辑与公事收缩逻辑对应 if (in_array($extension, array('css', 'js'))) { if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) { require_once 应用程式PATH.'libraries/Res迷你fier.php'; $resminifier = new ResMinifier(卡塔尔; //获取贮存财富版本的公文的数组变量 $resState = $resminifier->getResState(卡塔尔; //总结取安妥前文件版本号 $state = $resminifier->_getResStateVersion($filepathState of Qatar; //判定该版本号是还是不是留存 if (isset($resState[$object]卡塔尔(قطر‎卡塔尔国 { //决断是不是是.min.css或.min.js结尾 if (str_end_with($object, '.min.'.$extensionState of Qatar卡塔尔国 { //将版本号拼接上去,然后拿走min的公文路线 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔 - strlen($extension卡塔尔 - 4卡塔尔 . $state . '.' . $extension; } else { //将版本号拼接上去,然后拿走min的文本路线 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔国 - strlen($extension卡塔尔(قطر‎State of Qatar . $state . '.' . $extension; } //剖断min的不二等秘书籍是或不是存在在$resState里面 if (isset($resState[$minObject])) { $object = $minObject; $query = ''; } } } $file = RES_BASE_URL . $object; } return ($query == null) ? $file : ($file .'?'. $query); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
     * 智能路由资源真实路径
     * @param  string      路径
     * @param  string      扩展名
     * @return string       真实路径
     */
    function res_path($file, &$extension) {
        //检查是否存在查询字符串
        list($file, $query) = explode('?', $file . '?');
        //取得扩展名
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        //
        $file = str_replace('\', '/', $file);
        //取得当前控制器名
        global $class;
        if ($class == null) exit('can not get class name');
        $className = strtolower($class);
 
        //此处的规则是这样:
        //例如,如果不加 / ,Home控制器对应的格式是: index.css,那么 此处的路径会变成css/home/index.css
        //假如有 / ,控制器的格式可以是 /main.css,那么此处的路径会变成 css/main.css(公用的css类)
        if ('/' !== $file[0]) {
            //index.css => css/home/index.css
            $object = $extension .'/'. $className .'/' . $file;
        } else {
            // /css/main.css 或者 /main.css => css/main.css
            $object = substr($file, 1);
 
            //若object是 main.css ,则自动加上 扩展名目录 => css/main.css
            if (0 !== strncasecmp($extension, $object, strlen($extension))) {
                $object = $extension . '/' . $object;
            }
        }
        //资源真实路径
        $filepath = WEBROOT.'www/'.$object;
 
        //替换压缩版本,这部分逻辑与文件压缩逻辑对应
        if (in_array($extension, array('css', 'js'))) {
            if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) {
                require_once APPPATH.'libraries/ResMinifier.php';
                $resminifier = new ResMinifier();
                //获取存放资源版本的文件的数组变量
                $resState = $resminifier->getResState();
                //计算得到当前文件版本号
                $state = $resminifier->_getResStateVersion($filepath);
                //判断该版本号是否存在
                if (isset($resState[$object])) {
                    //判断是否是.min.css或.min.js结尾
                    if (str_end_with($object, '.min.'.$extension)) {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension;
                    } else {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                    }
                    //判断min的路径是否存在在$resState里面
                     if (isset($resState[$minObject])) {
                        $object = $minObject;
                        $query = '';
                     }
                }
 
            }
 
            $file = RES_BASE_URL . $object;
        }
 
        return ($query == null) ? $file : ($file .'?'. $query);
 
    }

代码基本上都给了讲授,方便大家轻易去精晓,前边风流洒脱部分是智能路线css、js能源的门道,前边意气风发部分是替换压缩版本,那生龙活虎有的的逻辑其实和能源收缩这里的逻辑基本等同,就是经过能源文件路线,举行决断和管理,最后拿到能源的收缩版本的路子,最后就将财富的减削版本的路线再次回到去,放在'<link rel=”stylesheet” type=”text/css” href=”‘ . $file . ‘”/>’里面。那样  ,就打响地将财富文件路线替换来了减弱版本的财富文件路线,而且在模板输出时,输出的是减削后的能源文件。

到此,能源替换的剧情就到此解说截止。而整少年老成项工夫也深入分析到此。

三、总结

在这里地小编集中地附着本博文疏解中的多少个文件代码:

Home.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Home extends MY_Controller { public function index() { $this->smartyData['test'] = 111; //那些暗中认可是加载 www/css/home/index.css文件 $this->addResLink('index.css'卡塔尔(قطر‎; //这么些私下认可是加载www/js/jquery.all.min.js文件 $this->addResLink('/jquery.all.min.js'卡塔尔国; //那么些默许是加载www/js/index.js文件 $this->addResLink('index.js'State of Qatar; $this->displayView('home/index.tpl'State of Qatar; } } 点击张开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Home extends MY_Controller {
    public function index() {
        $this->smartyData['test'] = 111;
        //这个默认是加载 www/css/home/index.css文件
        $this->addResLink('index.css');
        //这个默认是加载www/js/jquery.all.min.js文件
        $this->addResLink('/jquery.all.min.js');
        //这个默认是加载www/js/index.js文件
        $this->addResLink('index.js');
        $this->displayView('home/index.tpl');
    }
}
 
点击打开

My_Controller.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(卡塔尔(قطر‎; //压缩jscss财富文件 $this->compressResHandle(卡塔尔(قطر‎; } //==========================使用SMARTY模板引擎================================// /* 斯Matty母版页文件路线 */ protected $masterPage = 'default.tpl'; /* 视图像和文字件路径*/ protected $smartyView; /* 要赋值给smarty视图的数目*/ protected $smartyData = []; /* 能源文件*/ protected $_resLink = ['js'=>[], 'css'=>[]]; /** * 使用母版页输出一个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null卡塔尔国 { //为空则选择暗中同意母版 if ($masterPage == nullState of Qatar $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v卡塔尔(قطر‎; } //内容部分 $output .= $viewContent; //尾巴部分增多js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($vState of Qatar; } //发送最后输出结果以致服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DISportage.'Smarty.class.php'; $this->smarty = new 斯Matty(卡塔尔国; $this->smarty->setCompileDir(应用程式PATH . 'cache/'卡塔尔(قطر‎; $this->smarty->setCacheDir(应用软件PATH . 'cache/'卡塔尔(قطر‎; } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } } /** * 财富路线 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; } private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) { if ('/' === $viewName[0]卡塔尔(قطر‎ $viewName = substr($viewName, 1卡塔尔(قطر‎; //是或不是使用模板,有,则路由到 /views/master_page/*****.tpl下去 if ($masterPage) { $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage卡塔尔国; } //是不是设置模板目录 if ($setTemplateDirState of Qatar { $templateDir = VIEWPATH; $this->smarty->setTemplateDir($templateDir卡塔尔国; } } /** * 压缩js、css能源文件(优化) * @return [type] [description] */ private function compressResHandle(卡塔尔(قطر‎ { $this->load->library('ResMinifier'卡塔尔国; //压缩钦点文件夹下的能源文件 $this->resminifier->compressRes(State of Qatar; } } 点击张开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
 
    //==========================使用SMARTY模板引擎================================//
    /* Smarty母版页文件路径 */
    protected $masterPage = 'default.tpl';
    /* 视图文件路径*/
    protected $smartyView;
    /* 要赋值给smarty视图的数据*/
    protected $smartyData = [];
    /* 资源文件*/
    protected $_resLink = ['js'=>[], 'css'=>[]];
 
    /**
     * 使用母版页输出一个视图
     * @return [type] [description]
     */
    protected function displayView($viewName = null, $masterPage = null) {
        //为空则选用默认母版
        if ($masterPage == null) $masterPage = $this->masterPage;
        //获取视图的输出内容
        $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage);
 
        $output = '';
 
        //添加css Link
        foreach ($this->_resLink['css'] as $v) {
            $output .= res_link($v);
        }
 
        //内容部分
        $output .= $viewContent;
        //尾部添加js 链接
        foreach ($this->_resLink['js'] as $v) {
            $output .= res_link($v);
        }
        //发送最终输出结果以及服务器的 HTTP 头到浏览器
 
        $this->output->_display($output);
        return $output;
    }
 
    private function _fetchView($smartyData, &$viewName, &$masterPage) {
        if ($viewName == null) $viewName = $this->smartyView;
 
        if (empty($this->smarty)) {
            require_once SMARTY_DIR.'Smarty.class.php';
            $this->smarty = new Smarty();
            $this->smarty->setCompileDir(APPPATH . 'cache/');
            $this->smarty->setCacheDir(APPPATH . 'cache/');
        }
 
        //设置视图真实路径
        $this->_getViewDir(true, $viewName, $masterPage, $templateDir);
 
        foreach ($smartyData as $k => $v) {
            $this->smarty->assign($k, $v);
        }
 
        if (empty($masterPage)) {
            return $this->smarty->fetch($viewName);
        } else {
            $this->smarty->assign('VIEW_MAIN', $viewName);
            return $this->smarty->fetch($masterPage);
        }
    }
 
    /**
     * 资源路径
     * @param [type] $filePath [description]
     */
    protected function addResLink($filePath) {
        list($filePath, $query) = explode('?', $filePath . '?');
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        foreach ($this->_resLink as $v) {
            if (false === array_search($filePath, $this->_resLink[$extension])) {
                $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
            }
        }
 
        return $this;
    }
 
    private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) {
        if ('/' === $viewName[0]) $viewName = substr($viewName, 1);
 
        //是否使用模板,有,则路由到 /views/master_page/*****.tpl下去
        if ($masterPage) {
            $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage);
        }
 
        //是否设置模板目录
        if ($setTemplateDir) {
            $templateDir = VIEWPATH;
            $this->smarty->setTemplateDir($templateDir);
        }
    }
 
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library('ResMinifier');
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}
 
点击打开

ResMinifier.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 能源压缩类 */ class ResMinifier { /** 须要减小的能源目录*/ public $compressResDir = ['css', 'js']; /** 忽视压缩的路子,比如此处是js/icon最初的不二法门忽视压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 能源根目录*/ public $resRootDir; /** 能源版本文件路线*/ private $resStatePath; public function __construct(卡塔尔 { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes(卡塔尔国 { //获取贮存版本的能源文件 $resState = $this->getResState(卡塔尔(قطر‎; $count = 0; //开首遍历必要减小的能源目录 foreach ($this->compressResDir as $resDir卡塔尔国 { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTSState of Qatar卡塔尔(قطر‎ as $file卡塔尔 { //获取该能源文件的相对路线$filePath = str_replace('\', '/', $file->getRealPath(卡塔尔国卡塔尔; //获取文件绝对路线 $object = substr($filePath, strlen($this->resRootDir卡塔尔卡塔尔国; //总计文件的版本号 $state = $this->_getResStateVersion($file帕特h卡塔尔; //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension卡塔尔国State of Qatar { continue; } //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p决断是最重超过半数之风流倜傥*****************// //推断文件是不是留存且早就改成过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath卡塔尔卡塔尔国 { continue; } //确定保证/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); } $resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState); } /** * 获取能源文件有关新闻 * @param [type] $object 能源文件路线 (www/css/home/index.css卡塔尔国 * @param [type] $minObject 压缩财富文件路线 (www/min/css/home/index.ae123a.cssState of Qatar * @param [type] $needCompress 是还是不是供给压缩 * @param [type] $state 文件版本号 * @param [type] $extension 文件名后缀 * @return [type] [description] */ public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension卡塔尔(قطر‎ { //获取财富相对路线 $filePath = $this->resRootDir . $object; //判别能源是还是不是存在 if (!file_exists($filePathState of Qatar卡塔尔国 return "财富文件子虚乌有{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath卡塔尔国; //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSIONState of Qatar; //是还是不是要减少$needCompress = true; //判别财富文件是不是是以 .min.css只怕.min.js结尾的 //此类结尾通常都以已裁减过,比如jquery.min.js,就不用再压缩了 if (str_end_with($object, '.min.'.$extension, true卡塔尔(قطر‎卡塔尔国 { //压缩后的能源寄放路线,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔 - strlen($extension卡塔尔(قطر‎ - 4卡塔尔(قطر‎ . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir卡塔尔(قطر‎卡塔尔国 { //此处是必要减小的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔国 - strlen($extensionState of Qatar卡塔尔 . $state . '.' . $extension; //看看是还是不是是忽视的门路前缀 foreach ($this->compressResIngorePrefix as $vState of Qatar { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; } /** * 获取存放财富版本的公文 * 它是放在三个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; } /** * 总括文件的本子号,那一个是借助测算文件MD5散列值获得版本号 * 只要文件内容改变了,所计算得到的散列值就能够不相仿 * 用于决断财富文件是或不是有转移过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); } /** * 确定保障目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } } /** * 将核减后的财富文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}退步"卡塔尔(قطر‎; show_error("写入文件{$minFilePath}失利", -1State of Qatar; } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不帮忙压缩{extension}文件[$filePath]"); show_error("不协理压缩{extension}文件[$filePath]", -1); } } private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $contentState of Qatar; } } 点击展开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 资源压缩类
*/
class ResMinifier {
    /** 需要压缩的资源目录*/
    public $compressResDir = ['css', 'js'];
    /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
    public $compressResIngorePrefix = ['js/icon'];
    /** 资源根目录*/
    public $resRootDir;
    /** 资源版本文件路径*/
    private $resStatePath;
 
    public function __construct() {
        $this->resRootDir = WEBROOT . 'www/';
        $this->resStatePath = WEBROOT . 'www/resState.php';
    }
 
    public function compressRes() {
        //获取存放版本的资源文件
        $resState = $this->getResState();
        $count = 0;
 
        //开始遍历需要压缩的资源目录
        foreach ($this->compressResDir as $resDir) {
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                //获取该资源文件的绝对路径
                $filePath = str_replace('\', '/', $file->getRealPath());
 
                //获取文件相对路径
                $object = substr($filePath, strlen($this->resRootDir));
 
                //计算文件的版本号
                $state = $this->_getResStateVersion($filePath);
 
                //获取文件的几个参数值
                if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                    continue;
                }
 
                //压缩文件的绝对路径
                $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
 
                //************此处p判断是最重要部分之一*****************//
                //判断文件是否存在且已经改动过
                if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                    continue;
                }
 
                //确保/www/min/目录可写
                $this->_ensureWritableDir(dirname($minFilePath));
 
                if ($needCompress) {
                    $this->compressResFileAndSave($filePath, $minFilePath);
                } else {
                    copy($filePath, $minFilePath);
                }
 
                $resState[$object] = $state;
                $resState[$minObject] = '';
                $count++;
 
                if ($count == 50) {
                    $this->_saveResState($resState);
                    $count = 0;
                }
 
            }
        }
        if($count) $this->_saveResState($resState);
    }
 
    /**
     * 获取资源文件相关信息
     * @param  [type] $object       资源文件路径 (www/css/home/index.css)
     * @param  [type] $minObject    压缩资源文件路径 (www/min/css/home/index.ae123a.css)
     * @param  [type] $needCompress 是否需要压缩
     * @param  [type] $state        文件版本号
     * @param  [type] $extension    文件名后缀
     * @return [type]               [description]
     */
    public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
        //获取资源绝对路径
        $filePath = $this->resRootDir . $object;
        //判断资源是否存在
        if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
        //版本号
        $state = $this-> _getResStateVersion($filePath);
        //文件名后缀
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        //是否要压缩
        $needCompress = true;
 
        //判断资源文件是否是以 .min.css或者.min.js结尾的
        //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
        if (str_end_with($object, '.min.'.$extension, true)) {
            //压缩后的资源存放路径,放在 /www/min/ 目录下
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
            $needCompress = false;
        } else if (in_array($extension, $this->compressResDir)) {
            //此处是需要压缩的文件目录
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
            //看看是否是忽略的路径前缀
            foreach ($this->compressResIngorePrefix as $v) {
                if (str_start_with($object, $v, true)) {
                    $needCompress = false;
                }
            }
        } else {
            $minObject = 'min/'.$object;
            $needCompress = false;
        }
        return true;
    }
 
    /**
     * 获取存放资源版本的文件
     * 它是放在一个数组里
     * $resState = array(
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *     );
     * @return [type] [description]
     */
    public function getResState() {
        if (file_exists($this->resStatePath)) {
            require $this->resStatePath;
            return $resState;
        }
        return [];
    }
 
    /**
     * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
     * 只要文件内容改变了,所计算得到的散列值就会不一样
     * 用于判断资源文件是否有改动过
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    public function _getResStateVersion($filePath) {
        return base_convert(crc32(md5_file($filePath)), 10, 36);
    }
 
    /**
     * 确保目录可写
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    private function _ensureWritableDir($dir) {
        if (!file_exists($dir)) {
            @mkdir($dir, 0777, true);
            @chmod($dir, 0777);
        } else if (!is_writable($dir)) {
            @chmod($dir, 0777);
            if (!is_writable($dir)) {
                show_error('目录'.$dir.'不可写');
            }
        }
    }
 
    /**
     * 将压缩后的资源文件写入到/www/min/下去
     * @param  [type] $filePath    [description]
     * @param  [type] $minFilePath [description]
     * @return [type]              [description]
     */
    private function compressResFileAndSave($filePath, $minFilePath) {
        if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
 
            //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
            show_error("写入文件{$minFilePath}失败", -1);
        }
    }
 
    /**
     * 压缩资源文件
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    private function compressResFile($filePath) {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if ($extension === 'js') {
            require_once 'JShrink/Minifier.php';
            return JShrinkMinifier::minify(file_get_contents($filePath));
        } else if ($extension ==='css') {
            $content = file_get_contents($filePath);
            $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
            $content = str_replace(["rn", "r", "n"], '', $content);
            $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
            $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
            $content = str_replace(';}', '}', $content);
            return $content;
        } else {
            //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
            show_error("不支持压缩{extension}文件[$filePath]", -1);
 
        }
    }
 
    private function _saveResState($resState) {
        ksort($resState);
        $content = "<?phpnn$resState = array(n";
        foreach ($resState as $k => $v) {
            $content .= "t '$k' => '$v',n";
        }
        $content .= ");nn";
        file_put_contents($this->resStatePath, $content);
    }
 
}
 
点击打开

Common.php

PHP

<?php /** * 输出 HttpHead 中的财富总是。 css/js 自动判定真实路线 * @param string 文件路线 * @return string */ function res_link($file) { $file = res_path($file, $extension); if ($extension === 'css') { return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>'; } else if ($extension === 'js') { return '<script type="text/javascript" src="'.$file.'"></script>'; } else { return false; } } /** * 智能路由能源实际路线 * @param string 路径 * @param string 扩展名 * @return string 真实路线 */ function res_path($file, &$extension卡塔尔(قطر‎ { //检查是或不是留存询问字符串 list($file, $query卡塔尔 = explode('?', $file . '?'卡塔尔; //得到扩充名 $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); // $file = str_replace('\', '/', $fileState of Qatar; //取妥善前调整器名 global $class; if ($class == null卡塔尔 exit('can not get class name'卡塔尔; $className = strtolower($class卡塔尔(قطر‎; //此处的法则是如此: //例如,尽管不加 / ,Home调控器对应的格式是: index.css,那么 此处的路线会造成css/home/index.css //即使有 / ,控制器的格式可以是 /main.css,那么这里的路线会变成 css/main.css(公用的css类) if ('/' !== $file[0]) { //index.css => css/home/index.css $object = $extension .'/'. $className .'/' . $file; } else { // /css/main.css 只怕 /main.css => css/main.css $object = substr($file, 1卡塔尔; //若object是 main.css ,则自动抬高 扩充名目录 => css/main.css if (0 !== strncasecmp($extension, $object, strlen($extension卡塔尔卡塔尔卡塔尔国 { $object = $extension . '/' . $object; } } //财富真实路线 $filepath = WEBROOT.'www/'.$object; //替换压缩版本,那有个别逻辑与公事减弱逻辑对应 if (in_array($extension, array('css', 'js'))) { if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) { require_once APPPATH.'libraries/ResMinifier.php'; $resminifier = new Res迷你fier(卡塔尔; //获取贮存能源版本的公文的数组变量 $resState = $resminifier->getResState(卡塔尔; //总括取安妥前文件版本号 $state = $resminifier->_getResStateVersion($filepath卡塔尔(قطر‎; //剖断该版本号是不是存在 if (isset($resState[$object]卡塔尔国卡塔尔国 { //剖断是不是是.min.css或.min.js结尾 if (str_end_with($object, '.min.'.$extension卡塔尔国卡塔尔国 { //将版本号拼接上去,然后拿走min的文本路线 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔(قطر‎ - strlen($extensionState of Qatar - 4卡塔尔国 . $state . '.' . $extension; } else { //将版本号拼接上去,然后拿走min的文件路线 $minObject = 'min/'.substr($object, 0, strlen($object卡塔尔国 - strlen($extensionState of Qatar卡塔尔(قطر‎ . $state . '.' . $extension; } //判定min的门路是或不是存在在$resState里面 if (isset($resState[$minObject])) { $object = $minObject; $query = ''; } } } $file = RES_BASE_URL . $object; } return ($query == null) ? $file : ($file .'?'. $query); } /** * 判别 subject 是还是不是以 search早前, 参数钦赐是还是不是忽视大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_start_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len1 < $len2) return false; if ($ignore_case) { return 0 === strncmp($subject, $search, $len2); } else { return 0 === strncasecmp($subject, $search, $len2); } } /** * 推断 subject 是还是不是以 search结尾, 参数内定是还是不是忽视大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_end_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len2 > $len1) return false; if ($ignore_case卡塔尔国 { return 0 === strcmp(substr($subject, $len1 - $len2卡塔尔, $search卡塔尔; } else { return 0 === strcasecmp(substr($subject, $len1 - $len2卡塔尔国, $search卡塔尔; } } 点击张开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
    /**
     * 输出 HttpHead 中的资源连接。 css/js 自动判断真实路径
     * @param  string  文件路径
     * @return string      
     */
    function res_link($file) {
        $file = res_path($file, $extension);
 
        if ($extension === 'css') {
           return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>';
        } else if ($extension === 'js') {
            return '<script type="text/javascript" src="'.$file.'"></script>';
        } else {
            return false;
        }
    }
 
    /**
     * 智能路由资源真实路径
     * @param  string      路径
     * @param  string      扩展名
     * @return string       真实路径
     */
    function res_path($file, &$extension) {
        //检查是否存在查询字符串
        list($file, $query) = explode('?', $file . '?');
        //取得扩展名
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        //
        $file = str_replace('\', '/', $file);
        //取得当前控制器名
        global $class;
        if ($class == null) exit('can not get class name');
        $className = strtolower($class);
 
        //此处的规则是这样:
        //例如,如果不加 / ,Home控制器对应的格式是: index.css,那么 此处的路径会变成css/home/index.css
        //假如有 / ,控制器的格式可以是 /main.css,那么此处的路径会变成 css/main.css(公用的css类)
        if ('/' !== $file[0]) {
            //index.css => css/home/index.css
            $object = $extension .'/'. $className .'/' . $file;
        } else {
            // /css/main.css 或者 /main.css => css/main.css
            $object = substr($file, 1);
 
            //若object是 main.css ,则自动加上 扩展名目录 => css/main.css
            if (0 !== strncasecmp($extension, $object, strlen($extension))) {
                $object = $extension . '/' . $object;
            }
        }
        //资源真实路径
        $filepath = WEBROOT.'www/'.$object;
 
        //替换压缩版本,这部分逻辑与文件压缩逻辑对应
        if (in_array($extension, array('css', 'js'))) {
            if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) {
                require_once APPPATH.'libraries/ResMinifier.php';
                $resminifier = new ResMinifier();
                //获取存放资源版本的文件的数组变量
                $resState = $resminifier->getResState();
                //计算得到当前文件版本号
                $state = $resminifier->_getResStateVersion($filepath);
                //判断该版本号是否存在
                if (isset($resState[$object])) {
                    //判断是否是.min.css或.min.js结尾
                    if (str_end_with($object, '.min.'.$extension)) {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension;
                    } else {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                    }
                    //判断min的路径是否存在在$resState里面
                     if (isset($resState[$minObject])) {
                        $object = $minObject;
                        $query = '';
                     }
                }
 
            }
 
            $file = RES_BASE_URL . $object;
        }
 
        return ($query == null) ? $file : ($file .'?'. $query);
 
    }
 
    /**
     * 判断 subject 是否以 search开头, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_start_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len1 < $len2) return false;
        if ($ignore_case) {
            return 0 === strncmp($subject, $search, $len2);
        } else {
            return 0 === strncasecmp($subject, $search, $len2);
        }
    }
 
    /**
     * 判断 subject 是否以 search结尾, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_end_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len2 > $len1) return false;
        if ($ignore_case) {
            return 0 === strcmp(substr($subject, $len1 - $len2), $search);
        } else {
            return 0 === strcasecmp(substr($subject, $len1 - $len2), $search);
        }
    }
 
点击打开

$resState.php(里面包车型大巴代码是自动生成的卡塔尔国

XHTML

<?php $resState = array( 'css/home/index.css' => 'gwy933', 'js/echarts-all.min.js' => 'wqrf1c', 'js/home/index.js' => 's2z6f5', 'js/icon.js' => 'pgcyih', 'js/icon_home.js' => 'zhl9iu', 'js/ion.rangeSlider.min.js' => 'akq381', 'js/jquery-ui-autocomplete.js' => '8nzacv', 'js/jquery-ui.min.js' => 'i6tw8z', 'js/jquery.all.min.js' => 'd2w76v', 'js/jquery.city.js' => 'toxdrf', 'js/jquery.easydropdown.min.js' => '2ni3i0', 'js/jquery.matrix.js' => '3vrqkk', 'js/jquery.mobile.all.min.js' => 'ernu7r', 'js/jquery.qrcode.min.js' => 'yuhnsj', 'js/jquery.tinyscrollbar.min.js' => 'oakk3c', 'js/mobiscroll.custom.min.js' => 'kn8h2e', 'js/store.min.js' => 'n50jwr', 'js/swiper.animate1.0.2.min.js' => 'mm27zc', 'js/swiper.min.js' => 'jicwhh', 'min/css/home/index.6a4e83eb.css' => '', 'min/css/home/index.gwy933.css' => '', 'min/css/home/index.puzbnf.css' => '', 'min/css/home/index.thv8x7.css' => '', 'min/js/echarts-all.76025ee0.js' => '', 'min/js/echarts-all.wqrf1c.js' => '', 'min/js/home/index.65363d41.js' => '', 'min/js/home/index.s2z6f5.js' => '', 'min/js/icon.5bbd4db9.js' => '', 'min/js/icon.pgcyih.js' => '', 'min/js/icon_home.7fe74076.js' => '', 'min/js/icon_home.zhl9iu.js' => '', 'min/js/ion.rangeSlider.261d8ed1.js' => '', 'min/js/ion.rangeSlider.akq381.js' => '', 'min/js/jquery-ui-autocomplete.1f3bb62f.js' => '', 'min/js/jquery-ui-autocomplete.8nzacv.js' => '', 'min/js/jquery-ui.418e9683.js' => '', 'min/js/jquery-ui.i6tw8z.js' => '', 'min/js/jquery.all.2f248267.js' => '', 'min/js/jquery.all.d2w76v.js' => '', 'min/js/jquery.city.6b036feb.js' => '', 'min/js/jquery.city.toxdrf.js' => '', 'min/js/jquery.easydropdown.2ni3i0.js' => '', 'min/js/jquery.easydropdown.98fa138.js' => '', 'min/js/jquery.matrix.3vrqkk.js' => '', 'min/js/jquery.matrix.dfe2a44.js' => '', 'min/js/jquery.mobile.all.3539ebb7.js' => '', 'min/js/jquery.mobile.all.ernu7r.js' => '', 'min/js/jquery.qrcode.7d9738b3.js' => '', 'min/js/jquery.qrcode.yuhnsj.js' => '', 'min/js/jquery.tinyscrollbar.578e4cb8.js' => '', 'min/js/jquery.tinyscrollbar.oakk3c.js' => '', 'min/js/mobiscroll.custom.4a684f66.js' => '', 'min/js/mobiscroll.custom.kn8h2e.js' => '', 'min/js/store.536545cb.js' => '', 'min/js/store.n50jwr.js' => '', 'min/js/swiper.4650ad75.js' => '', 'min/js/swiper.animate1.0.2.517f82e8.js' => '', 'min/js/swiper.animate1.0.2.mm27zc.js' => '', 'min/js/swiper.jicwhh.js' => '', State of Qatar; 点击打开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
 
$resState = array(
     'css/home/index.css' => 'gwy933',
     'js/echarts-all.min.js' => 'wqrf1c',
     'js/home/index.js' => 's2z6f5',
     'js/icon.js' => 'pgcyih',
     'js/icon_home.js' => 'zhl9iu',
     'js/ion.rangeSlider.min.js' => 'akq381',
     'js/jquery-ui-autocomplete.js' => '8nzacv',
     'js/jquery-ui.min.js' => 'i6tw8z',
     'js/jquery.all.min.js' => 'd2w76v',
     'js/jquery.city.js' => 'toxdrf',
     'js/jquery.easydropdown.min.js' => '2ni3i0',
     'js/jquery.matrix.js' => '3vrqkk',
     'js/jquery.mobile.all.min.js' => 'ernu7r',
     'js/jquery.qrcode.min.js' => 'yuhnsj',
     'js/jquery.tinyscrollbar.min.js' => 'oakk3c',
     'js/mobiscroll.custom.min.js' => 'kn8h2e',
     'js/store.min.js' => 'n50jwr',
     'js/swiper.animate1.0.2.min.js' => 'mm27zc',
     'js/swiper.min.js' => 'jicwhh',
     'min/css/home/index.6a4e83eb.css' => '',
     'min/css/home/index.gwy933.css' => '',
     'min/css/home/index.puzbnf.css' => '',
     'min/css/home/index.thv8x7.css' => '',
     'min/js/echarts-all.76025ee0.js' => '',
     'min/js/echarts-all.wqrf1c.js' => '',
     'min/js/home/index.65363d41.js' => '',
     'min/js/home/index.s2z6f5.js' => '',
     'min/js/icon.5bbd4db9.js' => '',
     'min/js/icon.pgcyih.js' => '',
     'min/js/icon_home.7fe74076.js' => '',
     'min/js/icon_home.zhl9iu.js' => '',
     'min/js/ion.rangeSlider.261d8ed1.js' => '',
     'min/js/ion.rangeSlider.akq381.js' => '',
     'min/js/jquery-ui-autocomplete.1f3bb62f.js' => '',
     'min/js/jquery-ui-autocomplete.8nzacv.js' => '',
     'min/js/jquery-ui.418e9683.js' => '',
     'min/js/jquery-ui.i6tw8z.js' => '',
     'min/js/jquery.all.2f248267.js' => '',
     'min/js/jquery.all.d2w76v.js' => '',
     'min/js/jquery.city.6b036feb.js' => '',
     'min/js/jquery.city.toxdrf.js' => '',
     'min/js/jquery.easydropdown.2ni3i0.js' => '',
     'min/js/jquery.easydropdown.98fa138.js' => '',
     'min/js/jquery.matrix.3vrqkk.js' => '',
     'min/js/jquery.matrix.dfe2a44.js' => '',
     'min/js/jquery.mobile.all.3539ebb7.js' => '',
     'min/js/jquery.mobile.all.ernu7r.js' => '',
     'min/js/jquery.qrcode.7d9738b3.js' => '',
     'min/js/jquery.qrcode.yuhnsj.js' => '',
     'min/js/jquery.tinyscrollbar.578e4cb8.js' => '',
     'min/js/jquery.tinyscrollbar.oakk3c.js' => '',
     'min/js/mobiscroll.custom.4a684f66.js' => '',
     'min/js/mobiscroll.custom.kn8h2e.js' => '',
     'min/js/store.536545cb.js' => '',
     'min/js/store.n50jwr.js' => '',
     'min/js/swiper.4650ad75.js' => '',
     'min/js/swiper.animate1.0.2.517f82e8.js' => '',
     'min/js/swiper.animate1.0.2.mm27zc.js' => '',
     'min/js/swiper.jicwhh.js' => '',
);
 
点击打开

 

别的附上JShrink那几个PHP类的链接给大家下载 

只要我们依旧以为非常不足OK的话,小编一向将以此实验项目打包供大家下载下来学习和询问:

四、结语

最终自身来享受大家线上类别的现实贯彻方案:

我们的类别分线上意况、开垦景况和测量检验情况,在付出和测量检验情状中,大家每贰回访谈都会调用压缩文件的接口,然后再对转移的财富文件的尺寸是要做决断的,假如削减后文件过小,将要求将该财富文件的代码合併到任何能源文件里去,以此减弱不供给的HTTP诉求(因为文件太小,能源的下载时间远小于HTTP央求响应所开支的流年);另叁个是图表的拍卖,全体图片都要因此压缩本事因而(举例在:  这一个网址去减弱图片),在PC端,假使是小Logo的话,使用图片合併的章程进行优化,详细情形可参看本身的那篇博文:http://www.cnblogs.com/it-cen/p/4618954.html    而在wap端的图样管理利用的是base64编码方式来管理图片,详细情形能够参见本身的这篇博文:  ,当页面输出时,会选取redis来缓存页面(为什么用内部存款和储蓄器来缓存并非选取页面缓存,这些未来再享受给我们)。假若是线上情形,每发二遍版本,才会调用一下财富文件减弱这些接口,並且线上的静态财富(css、js、图片)是寄存在Ali云的OSS里的,与大家的应用服务器是分离的。那是大家线上类别的风度翩翩有些优化解决方案,当然了,还大概有越来越多优化本事,笔者会在后来各种总计和享受出来,方便我们协同学学和交换。

本次博文就享受到此,多谢观望此博文的恋人们。

1 赞 1 收藏 评论

图片 7

本文由王中王鉄算盘开奖结果发布于品牌动态,转载请注明出处:静态资源文件自动压缩并替换成压缩版本

关键词: