图片 7

静态资源文件自动压缩并替换成压缩版本,生成html静态文件类程序与实例使用方法

静态能源文件自动减削并替换来压缩版本(大型网址优化本事卡塔尔国

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

原稿出处: Kelly   

那三遍,作者计算和享受生龙活虎项大型网址优化技能,那就是在项目中活动减削静态能源文件(css、js),并让网址自行加载压缩后的财富文件。当然,那项技能在雅虎35条前端优化提出里也许有记载,但它这只是给出三个答辩的方案而已,並且接纳的是表面压缩工具去减弱,而在作者的项目中,是直接通过协调的次第自动化去收缩全体css、js文件,然后让页面一贯加载所缩小后的财富,接下去直接走入正题。

此番实验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的境况(英特网搭建无论是搭建LAMP还是LNMP的学科都丰富多彩手忙脚乱,下一次小编会计算和享用怎么样在LINUX下搭建服务器碰着的博文,并且搭建的条件必得三次性搭建设成功的卡塔尔国。所采纳的框架是CI框架,所接纳的沙盘是Smarty模板引擎。当然了,那么些只是本人所选取的条件而已,如若你是PHP开荒者,倘令你要测量检验下本次试验,那么,我建议您的PHP版本选拔5.4上述,至于框架用什么样都以能够的。而意气风发旦您不是PHP开垦者(你是JSP可能是ASP开拓者或者是其他开垦者卡塔 尔(英语:State of Qatar),那么你理解好那生龙活虎思路后,完全可以在和煦熟知的言语里张开尝试测量检验。

一、原理图

第后生可畏笔者画一张思路图,便于大家先知道。

率先是能源减少原理图:

图片 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() { $this->load->library(‘ResMinifier’);
//压缩内定文件夹下的财富文件 $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() { $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->getReal帕特h());
//获取文件相对路线 $object = substr($file帕特h,
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
“能源文件一纸空文{$file帕特h}”; //版本号 $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(“写入文件{$minFile帕特h}败北”, -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
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_DOTS)) as $file) { //获取该财富文件的相对路线$filePath = str_replace(‘\’, ‘/’, $file->getRealPath());
//获取文件相对路线 $object = substr($filePath,
strlen($this->resRootDir)); //总括文件的版本号 $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目录里的公文都成为路线方式,

比如说获取文件的相对路线 $file帕特h 的值是那样子的:

/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()方法,这里获得到压缩文件的相对路线$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,
&$extension) { //获取能源相对路线 $file帕特h = $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; }

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))
那个论断是相比能源文件路线字串尾巴部分是还是不是以 .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 $v) { 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($minFile帕特h),那些是决断压缩文件路线是还是不是留存,况且该压缩文件是不是真正存在目录中。

看下意气风发段代码,假设能走到这一片段,表达当前的那一个财富文件是被改过过的(代码改善过卡塔 尔(英语:State of Qatar),那么那个时候就对文本进行裁减操作了

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
($needCompress),那一个论断能源文件是还是不是须要减弱,须要的话调用$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($file帕特h);
此方法中分两类压缩,第一类时对js文件举行压缩,第二类的对css文件进行减少。先说js压缩,这里是调用二个JShrink的类,它

八个用来压缩js文件的PHP类,百度能够找到,调用这些类的minify()这么些措施就足以减小了;而css的滑坡利用正则替换来压缩,把这么些空格换行什么的都去掉。到此就缩小成功

了,然后再将裁减后的能源写入到相应的压缩文件路线里去。

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

随即继续看compressRes()那么些情势里的代码,这里最先便是保存新的本子号到$resState数组里
$object=>$state,还会有便是新的减少路线$minObject,而这里$count++的效果与利益是,当以此轮回46遍就将
$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($resState),这几个措施正是将$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’);
//这几个默许是加载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(); }
//==========================使用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_DI揽胜极光.’斯马特y.class.php’; $this->smarty = new 斯马特y();
$this->smarty->setCompileDir(APPPATH . ‘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 ($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

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’);

大家看那么些法子:

PHP

/** * 使用母版页输出多个视图 * @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_DIEnclave.’Smarty.class.php’; $this->smarty = new Smarty();
$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); } }

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模板引擎的内容,那个关于斯马特y的文化作者就不讲了,大家能够友善百度,这里关键讲
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=”‘%20.%20$file%20.%20′”/>’; }
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="’%20.%20$file%20.%20’"/>’;
        } else if ($extension === ‘js’) {
            return ‘<script type="text/javascript" src="’.$file.’"></script>’;
        } else {
            return false;
        }
    }

那边最关键就是 res_path() 函数了,那个函数能自动路由能源的真实性路径。譬喻: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(‘\’, ‘/’, $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); }

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’);
$this->displayView(‘home/index.tpl’); } } 点击张开

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模板引擎================================//
/* 斯马特y母版页文件路线 */ 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_DIEnclave.’斯马特y.class.php’; $this->smarty = new Smarty();
$this->smarty->setCompileDir(APPPATH . ‘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 ($setTemplateDir) {
$templateDir = VIEWPATH;
$this->smarty->setTemplateDir($templateDir); } } /** *
压缩js、css能源文件(优化卡塔尔 * @return [type] [description] */
private function compressResHandle() {
$this->load->library(‘ResMinifier’); //压缩内定文件夹下的能源文件
$this->resminifier->compressRes(); } } 点击展开

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_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); } } 点击张开

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(‘\’, ‘/’, $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); } } 点击展开

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="’%20.%20$file%20.%20’"/>’;
        } 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’ => ”, ); 点击展开

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来缓存页面(为什么用内部存款和储蓄器来缓存而不是应用页面缓存,这几个以往再享受给大家卡塔 尔(英语:State of Qatar)。要是是线上情状,每发一次版本,才会调用一下财富文件减弱这几个接口,何况线上的静态能源(css、js、图片卡塔 尔(英语:State of Qatar)是存放在Ali云的OSS里的,与我们的应用服务器是分开的。那是大家线上类其他黄金时代局地优化施工方案,当然了,还应该有越多优化技艺,作者会在现在种种总计和分享出去,方便我们一块儿学学和交换。

本次博文就享受到此,谢谢阅览此博文的敌人们。

1 赞 1 收藏
评论

图片 7

文本上传例子

class html
{
var $dir; //dir for the htmls(without/)
var $rootdir; //root of html files(without/):html
var $name; //html文件贮存路线
var $dirname; //钦命的公文夹名称
var $url; //获取html文件音信的根源网页地址
var $time; //html文件消息填加时的日子
var $dirtype; //目录寄存方式:year,month,,,,
var $nametype; //html文件命名方式:name

 代码如下

function html($nametype=’name’,$dirtype=’year’,$rootdir=’html’)

<?php
header(‘content-type:text/html;charset=utf-8’);
require(‘uploadFile.php’);

function setvar($nametype=’name’,$dirtype=’year’,$rootdir=’html’)

if(isset($_POST[‘submit’])){
$uploads = $_FILES[‘file’];
$num_file = count($uploads[‘name’]);

function createdir($dir=”)
{
$this->dir=$dir?$dir:$this->dir;

$up = new UploadFile($uploads,’uploads’,1024);
$num = $up->upload();

if (!is_dir($this->dir))
{
$temp = explode(‘/’,$this->dir);
$cur_dir = ”;
for($i=0;$i {
$cur_dir .= $temp[$i].’/’;
if (!is_dir($cur_dir))

if($num == $num_file ){
echo ‘全体文书上传成功’;
exit;
}else{
echo $num,’个文件上传成功<br/>’;
echo $up->showErrorInfo();
exit;
}
}

}
}
}

?>

function getdir($dirname=”,$time=0)
{
$this->time=$time?$time:$this->time;
$this->dirname=$dirname?$dirname:$this->dirname;

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“;
<html xmlns=” 1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″
/>
<title>无标题文书档案</title>
</head>

switch($this->dirtype)
{
case ‘name’:
if(empty($this->dirname))
$this->dir=$this->rootdir;
else
$this->dir=$this->rootdir.’/’.$this->dirname;
break;
case ‘year’:
$this->dir=$this->rootdir.’/’.date(“Y”,$this->time);
break;

<body>
<form action=”uup.php” method=”post”
enctype=”multipart/form-data”>
<p><input name=”file[]” type=”file” /></p>
<p><input name=”file[]” type=”file” /></p>
<p><input name=”file[]” type=”file” /></p>
<p><input name=”file[]” type=”file” /></p>
<input name=”submit” type=”submit” />
</form>
</body>
</html>

case ‘month’:
$this->dir=$this->rootdir.’/’.date(“Y-m”,$this->time);
break;

文件上传类代码

case ‘day’:
$this->dir=$this->rootdir.’/’.date(“Y-m-d”,$this->time);
break;
}

 代码如下

$this->createdir();

<?php
/*————*/
class UploadFile
{
var $user_post_file  = array();
var $save_file_path  = ”;
var $max_file_size   = ”;
var $allow_type      =
array(‘gif’,’jpg’,’png’,’zip’,’rar’,’txt’,’doc’,’pdf’);
var $final_file_path = ”;
var $save_info       = array();
var $error_info      = array();

return $this->dir;
}

/**
*构造函数,用于最初化消息。
*
*@param Array $file
*@param String $path
*@param Integer $size
*@param Array $type
*/
function __construct($file,$path,$size = 2097152,$type=”)
{
$this->user_post_file   = $file;
$this->save_file_path   = $path;
$this->max_file_size    = $size;
if(!$type=”){
$this->allow_type[] = $type;
}
}

function geturlname($url=”)
{
$this->url=$url?$url:$this->url;

/**
*
*
*@access public
*@return int
*/
function upload()
{
for($i=0;$i<count($this->user_post_file[‘name’]);$i++)
{
if($this->user_post_file[‘error’][$i] ==
0){//上传文件状态通常
//获取当前文件名,不经常文件名,大小,类型,扩展名
$name     = $this->user_post_file[‘name’][$i];
$tmp_name = $this->user_post_file[‘tmp_name’][$i];
$size     = $this->user_post_file[‘size’][$i];
$type     = $this->user_post_file[‘type’][$i];
$ext_name = $this->getExtName($name);

$filename=basename($this->url);
$filename=explode(“.”,$filename);
return $filename[0];
}

//文件大小
if(!$this->checkSize($size)){
$this->error_info[] = ‘您上传的文件:’.$name.’太大’;
continue;
}
//扩展名
if(!$this->checkType($ext_name)){
$this->error_info[] = ‘您上传的文书:’.$name.’违规’;
continue;
}
//违规上传
if(!is_uploaded_file($tmp_name)){
$this->error_info[] = ‘您上传的公文:’.$name.’归属非法提交’;
continue;
}

case ‘nametime’:
$this->name=$this->dir.’/’.$this->geturlname().’-‘.$this->time.’.htm’;
break;

//
$basename = $this->getBaseName($name,”.”.$ext_name);
$final_filename =
$basename.’-‘.time().’-‘.rand(1,10000).’.’.$ext_name;
$this->final_file_path =
$this->save_file_path.’/’.$final_filename;

}
return $this->name;
}

if(!move_uploaded_file($tmp_name,$this->final_file_path)){
$this->error_info = $this->user_post_file[‘error’][$i];
continue;
}

function createhtml($url=”,$time=0,$dirname=”,$htmlname=”)
{
$this->url=$url?$url:$this->url;
$this->dirname=$dirname?$dirname:$this->dirname;
$this->time=$time?$time:$this->time;
//上面保障不重复地把变量给与该类成员
if(empty($htmlname))
$this->getname();
else
$this->name=$dirname.’/’.$htmlname; //得到name

//
$this->save_info[] = array(
“name” => $name,
“ext_name” => $ext_name,
          “type” => $type,
                            “size” => $size,
“final_filename” => $final_filename,
                            “path” => $this->final_file_path
);
}
}

$content=file($this->url) or die(“Failed to open the url
“.$this->url.” !”);;

return count($this->save_info);
}

///////////////关键步—用file读取$this->url

/*
 *检查客户上传文件的分寸时候合法
 *
 *@param Integer $size
 *@access private
 *@return boolean
 */
function checkSize($size)
{
if($size > $this->max_file_size){
return FALSE;
}

$content=join(“”,$content);
$fp=@fopen($this-%3Ename,%22w“) or die(“Failed to open the file
“.$this->name.” !”);
if(@fwrite($fp,$content))
return true;
else
return false;
fclose($fp);
}
/////////////////以name为名字生成html

return TRUE;
}

function deletehtml($url=”,$time=0,$dirname=”)
{
$this->url=$url?$url:$this->url;
$this->time=$time?$time:$this->time;

/*
 *检查客商上传文件的类型是或不是合法
 *
 *@access private
 *@return boolean
 */
function checkType($extension)
{
foreach($this->allow_type
as $type){
if(strcasecmp($extension,$type) == 0){
return TRUE;
}
}

$this->getname();

return FALSE;
}

if(@unlink($this->name))
return true;
else
return false;
}

/*
 *获得文件的增添名
 *
 *@param string $filename
 *@access private
 *@return string
 */
function getExtName($filename)
{
$p = pathinfo($filename);

/**
* function::deletedir()
* 删除目录
* @param $file 目录名(不带/)
* @return 
*/
function deletedir($file)
{
if(file_exists($file))
{
if(is_dir($file))
{
$handle =opendir($file);
while(false!==($filename=readdir($handle)))

return $p[‘extension’];
}

closedir($handle);
rmdir($file);
return true;
}else
}
}

/*
 *收获文件名(不包涵扩展名卡塔 尔(英语:State of Qatar)
 *
 *@param string $filename
 *@param string $type
 *@access private
 *@return boolean
 */
function getBaseName($filename,$ext_name)
{
$basename = basename($filename,$ext_name);

}
?>

return $basename;
}

/*
 *
 *
 *
 */
function showErrorInfo()
{
if(count($this->error_info) != 0){
//echo ‘error…<br/>’;
foreach($this->error_info as $k=>$v){
echo ($k+1),’:’,$v,'<br/>’;
}
}
}

function getSaveInfo()
{
return $this->save_info;
}
}

//$upload = new UploadFile(”,”);
//$upload = new UploadFile();
//$upload->showErrorInfo();

?>

发表评论

电子邮件地址不会被公开。 必填项已用*标注