快捷搜索:
来自 新京葡娱乐场网址 2019-06-15 16:06 的文章
当前位置: 67677新澳门手机版 > 新京葡娱乐场网址 > 正文

大型网站优化技术,多图片上传程序代码

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

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('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->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
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存放能源根目录的

$resState帕特h 那一个是能源版本文件路线

(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) { //获取该资源文件的相对路线$file帕特h = str_replace('\', '/', $file->getRealPath()); //获取文件相对路线 $object = substr($file帕特h, 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) { //获取能源绝对路线 $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; }

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("写入文件{$minFilePath}退步", -1); } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]** ([^/][^*]** )*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s /', '$1', $content); $content = preg_replace('/s ([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]"); show_error("不协助压缩{extension}文件[$filePath]", -1); } }

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

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

咱俩先看下那些压缩方法:

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

八个用来压缩js文件的PHP类,百度得以找到,调用那些类的minify()这几个方法就能够减少了;而css的缩减利用正则替换成压缩,把那一个空格换行什么的都去掉。到此就收缩成功

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

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

接着继续看compressRes()那个措施里的代码,这里起初正是保存新的本子号到$resState数组里 $object=>$state,还会有便是新的裁减路线$minObject,而这里$count 的功用是,当以此轮回四十七遍就将 $resState这几个数组写入二遍到 resState.php文件里,这里是出于审慎牵记而已,若是你不加那么些$count的拍卖那有的也得以,最后写入一次就行了。

PHP

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

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

这里看$this->_saveResState($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酷威.'Smarty.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('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_DI昂科雷.'Smarty.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); } }

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

这一段代码未有一部分正是调用了斯玛特y模板引擎的内容,这些关于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模板引擎================================// /* 斯马特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_DISportage.'斯Matty.class.php'; $this->smarty = new 斯Matty(); $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(); } } 点击展开

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->getReal帕特h()); //获取文件相对路线 $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 应用程式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); } /** * 决断 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端,如若是小图标的话,使用图片合并的艺术张开优化,详细的情况可参照他事他说加以考查本人的那篇博文: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;

本文由67677新澳门手机版发布于新京葡娱乐场网址,转载请注明出处:大型网站优化技术,多图片上传程序代码

关键词: