>

多图片上传程序代码,大型网址优化才能

- 编辑:至尊游戏网站 -

多图片上传程序代码,大型网址优化才能

静态能源文件自动削减并替换来压缩版本(大型网址优化技巧)

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

原著出处: Kelly   

那二次,作者总括和享受一项大型网址优化技艺,那正是在类型中自动削减静态财富文件(css、js),并让网址自动加载压缩后的能源文件。当然,那项手艺在雅虎35条前端优化建议里也可能有记载,但它那只是给出二个争辩的方案而已,並且使用的是表面压缩工具去减少,而在自家的体系中,是直接通过和谐的程序自动化去收缩全体css、js文件,然后让页面一贯加载所减少后的能源,接下去直接进入正题。

此次试验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的条件(英特网搭建无论是搭建LAMP照旧LNMP的课程都精彩纷呈非常倒霉,下一次笔者会计算和享用怎么样在LINUX下搭建服务器情形的博文,何况搭建的情状必需二次性搭建成功的)。所选拔的框架是CI框架,所使用的沙盘是斯马特y模板引擎。当然了,那几个只是笔者所利用的情状而已,即使你是PHP开拓者,要是你要测量试验下这一次实验,那么,笔者提出你的PHP版本选择5.4上述,至于框架用什么样都以足以的。而一旦你不是PHP开垦者(你是JSP恐怕是ASP开荒者或然是别的开辟者),那么您知道好这一思路后,完全能够在和谐深谙的言语里开展实验测量检验。

一、原理图

第一自身画一张思路图,便于大家先明了。

率先是能源减弱原理图:

图片 1

接着是财富文件替换的规律图:

图片 2

若果我们认真明白何况看懂这两张原理图的话,基本上也就调控了本身所享用的思路。假设仍然无法知道的话,接下去笔者会结合代码,对以上原理图的每一步实行详尽解说。

二、思路详细分析

1.第一是调用该滑坡的艺术,你能够把该情势放在网址所要加载的公共类的地方,比如每便访谈网址都会调用该滑坡方法开展削减。当然,那些只是在支付意况才会每一趟都调用,假如是线上的条件,在您的网址发一遍新本子的时候,调用一回用来生成压缩版的静态能源就足以了。

class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); //压缩jscss能源文件 $this->compressResHandle(); } /** * 压缩js、css能源文件(优化) * @return [type] [description] */ private function compressResHandle() { $this->load->library('Res迷你fier'); //压缩内定文件夹下的财富文件 $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.接着就调用了 Res迷你fier类里的 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->getRealPath()); //获取文件相对路线 $object = substr($file帕特h, strlen($this->resRootDir)); //总括文件的版本号 $state = $this->_getResStateVersion($filePath); //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; } //压缩文件的相对路线 $minFile帕特h = 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("写入文件{$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
<?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);
    }
 
}
 
点击打开 资源压缩类

方方面面类超越51%代码我都加了疏解,方便我们非常的慢领会。这里作者也会对每一行代码进行表明。

(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() 方法来获得寄放版本的能源文件,此处先跳到该方式看看是什么写的,其实正是包罗该文件,然后回来里面存放版本号的数组,大家看注释能够清楚该文件里存放版本号的格式(顺便附上海体育场地让大家看看)

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目录里的文本都改成路线形式,

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

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

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

css/home/index.css

此间就从头调用$this->_getResStateVersion($filePath)来计量文件的版本号

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

PHP

/** * 总结文件的本子号,这几个是依赖估测计算文件MD5散列值获得版本号 * 只要文件内容改造了,所总结获得的散列值就能差异 * 用于判别能源文件是或不是有退换过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); }

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

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

依然到版本号后,再看下一段代码,这里开头调用$this->getObjectInfo()方法,这里收获到压缩文件的相对路线$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($minFilePath),那些是决断压缩文件路线是或不是存在,况且该压缩文件是或不是真实存在目录中。

看下一段代码,假使能走到这一部分,表明当前的那些财富文件是被改换过的(代码修改过),那么此时就对文件进行压缩操作了

PHP

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

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

$this->_ensureWritableDir(),此措施是要力保新创建的www/min目录是可写的,这里附上代码:

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

PHP

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

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

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

if ($needCompress),那些论断财富文件是或不是须要减弱,须要的话调用$this->compressResFileAndSave($filePath, $minFilePath);不需求的话,直接复制文件到压缩文件路线 copy($filePath, $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("写入文件{$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); } }

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

先削减,再将减小后的情节写入到 压缩文件路线里去。

咱俩先看下这一个压缩方法:

$this->compressResFile($filePath); 此方法中分两类压缩,第一类时对js文件进行压缩,第二类的对css文件举行削减。先说js压缩,这里是调用三个JShrink的类,它

二个用来压缩js文件的PHP类,百度能够找到,调用那些类的minify()那个法子就足以收缩了;而css的削减利用正则替换到收缩,把那贰个空格换行什么的都去掉。到此就缩短成功

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

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

进而继续看compressRes()那一个艺术里的代码,这里开首就是保存新的本子号到$resState数组里 $object=>$state,还应该有正是新的缩小路线$minObject,而那边$count++的功能是,当以此轮回肆十五回就将 $resState那些数组写入二次到 resState.php文件里,这里是出于严慎思索而已,倘令你不加这个$count的拍卖那部分也得以,最后写入三遍就行了。

PHP

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

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

这里看$this->_saveResState($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模板引擎================================// /* 斯马特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_DIPRADO.'斯Matty.class.php'; $this->smarty = new Smarty(); $this->smarty->setCompileDir(应用程式PATH . '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

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_DIRAV4.'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模板引擎的内容,那一个关于Smarty的知识小编就不讲了,大家可以和谐百度,这里根本讲 res_link() 那些函数,即是经过这一个函数来实行财富文件替换的。先看这么些函数的代码:

PHP

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

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

此处最要害就是 res_path() 函数了,这些函数能活动路由财富的真人真事路线。比如: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 应用软件PATH.'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模板引擎================================// /* 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_DIENVISION.'斯玛特y.class.php'; $this->smarty = new 斯马特y(); $this->smarty->setCompileDir(应用程式PATH . '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('Res迷你fier'); //压缩钦定文件夹下的能源文件 $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("写入文件{$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
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="' . $file . '"/>';
        } else if ($extension === 'js') {
            return '<script type="text/javascript" src="'.$file.'"></script>';
        } else {
            return false;
        }
    }
 
    /**
     * 智能路由资源真实路径
     * @param  string      路径
     * @param  string      扩展名
     * @return string       真实路径
     */
    function res_path($file, &$extension) {
        //检查是否存在查询字符串
        list($file, $query) = explode('?', $file . '?');
        //取得扩展名
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        //
        $file = str_replace('\', '/', $file);
        //取得当前控制器名
        global $class;
        if ($class == null) exit('can not get class name');
        $className = strtolower($class);
 
        //此处的规则是这样:
        //例如,如果不加 / ,Home控制器对应的格式是: index.css,那么 此处的路径会变成css/home/index.css
        //假如有 / ,控制器的格式可以是 /main.css,那么此处的路径会变成 css/main.css(公用的css类)
        if ('/' !== $file[0]) {
            //index.css => css/home/index.css
            $object = $extension .'/'. $className .'/' . $file;
        } else {
            // /css/main.css 或者 /main.css => css/main.css
            $object = substr($file, 1);
 
            //若object是 main.css ,则自动加上 扩展名目录 => css/main.css
            if (0 !== strncasecmp($extension, $object, strlen($extension))) {
                $object = $extension . '/' . $object;
            }
        }
        //资源真实路径
        $filepath = WEBROOT.'www/'.$object;
 
        //替换压缩版本,这部分逻辑与文件压缩逻辑对应
        if (in_array($extension, array('css', 'js'))) {
            if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) {
                require_once APPPATH.'libraries/ResMinifier.php';
                $resminifier = new ResMinifier();
                //获取存放资源版本的文件的数组变量
                $resState = $resminifier->getResState();
                //计算得到当前文件版本号
                $state = $resminifier->_getResStateVersion($filepath);
                //判断该版本号是否存在
                if (isset($resState[$object])) {
                    //判断是否是.min.css或.min.js结尾
                    if (str_end_with($object, '.min.'.$extension)) {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension;
                    } else {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                    }
                    //判断min的路径是否存在在$resState里面
                     if (isset($resState[$minObject])) {
                        $object = $minObject;
                        $query = '';
                     }
                }
 
            }
 
            $file = RES_BASE_URL . $object;
        }
 
        return ($query == null) ? $file : ($file .'?'. $query);
 
    }
 
    /**
     * 判断 subject 是否以 search开头, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_start_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len1 < $len2) return false;
        if ($ignore_case) {
            return 0 === strncmp($subject, $search, $len2);
        } else {
            return 0 === strncasecmp($subject, $search, $len2);
        }
    }
 
    /**
     * 判断 subject 是否以 search结尾, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_end_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len2 > $len1) return false;
        if ($ignore_case) {
            return 0 === strcmp(substr($subject, $len1 - $len2), $search);
        } else {
            return 0 === strcasecmp(substr($subject, $len1 - $len2), $search);
        }
    }
 
点击打开

$resState.php(里面包车型客车代码是自动生成的)

XHTML

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

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

 

其余附上JShrink那一个PHP类的链接给咱们下载 

倘使大家照旧以为相当不够OK的话,小编直接将以此实验项目打包供大家下载下来学习和询问:

四、结语

最后本人来分享大家线上项目标现实性贯彻方案:

我们的项目分线上景况、开辟条件和测验情形,在支付和测量试验意况中,大家每二回访问都会调用压缩文件的接口,然后再对转移的能源文件的分寸是要做判别的,即使缩减后文件过小,将要求将该财富文件的代码合併到其余国资本源文件里去,以此减弱不要求的HTTP央求(因为文件太小,能源的下载时间远远低于HTTP央浼响应所费用的时光);另叁个是图片的管理,全体图片都要透过压缩才具透过(比如在:  这些网址去收缩图片),在PC端,要是是小Logo的话,使用图片合併的办法开展优化,详细情况可参照自己的那篇博文:http://www.cnblogs.com/it-cen/p/4618954.html    而在wap端的图片管理利用的是base64编码格局来管理图片,详细情况能够参照本身的那篇博文:  ,当页面输出时,会动用redis来缓存页面(为什么用内存来缓存并不是使用页面缓存,那几个将来再享受给大家)。即便是线上情状,每发二遍版本,才会调用一下财富文件减少这么些接口,何况线上的静态资源(css、js、图片)是存放在在Ali云的OSS里的,与我们的应用服务器是分开的。那是大家线上项指标一部分优消除决方案,当然了,还应该有越来越多优化本领,笔者会在今后各种计算和享受出来,方便大家齐声上学和调换。

本次博文就享受到此,多谢观看此博文的朋友们。

1 赞 1 收藏 评论

图片 7

文件上传例子

 代码如下

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

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

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

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

?>

<!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>

<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>

文本上传类代码

 代码如下

<?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();

/**
*构造函数,用于开端化音讯。
*
*@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;
}
}

/**
*
*
*@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);

//文件大小
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;
}

//
$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;

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

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

return count($this->save_info);
}

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

return TRUE;
}

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

return FALSE;
}

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

return $p['extension'];
}

/*
 *收获文件名(不富含增加名)
 *
 *@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();

?>

本文由设计建站发布,转载请注明来源:多图片上传程序代码,大型网址优化才能