来自 公司简介 2019-09-25 06:36 的文章
当前位置: 澳门太阳娱乐手机登录 > 公司简介 > 正文

重型网址优化技能,php多文件上传

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

2015/11/26 · HTML5 · 静态财富

原版的书文出处: Kelly   

那叁遍,作者总括和享用一项大型网址优化技艺,那正是在类型中自动削减静态能源文件(css、js),并让网址活动加载压缩后的财富文件。当然,那项手艺在雅虎35条前端优化提出里也可以有记载,但它那只是给出叁个争执的方案而已,並且应用的是外表压缩工具去减少,而在本人的品类中,是直接通过投机的顺序自动化去减弱全数css、js文件,然后让页面平昔加载所减弱后的能源,接下去直接进去正题。

此番实验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的景况(互联网搭建无论是搭建LAMP仍然LNMP的教程都五颜六色一无可取,后一次笔者会计算和分享什么在LINUX下搭建服务器遇到的博文,并且搭建的条件必得叁遍性搭建成功的)。所采纳的框架是CI框架,所接纳的模版是Smarty模板引擎。当然了,这几个只是本身所运用的遇到而已,假诺您是PHP开辟者,纵然你要测验下这一次试验,那么,小编提出您的PHP版本接纳5.4以上,至于框架用怎么样都以能够的。而一旦你不是PHP开辟者(你是JSP或许是ASP开采者或许是任何开荒者),那么你精晓好这一思路后,完全能够在团结深谙的语言里张开尝试测验。

一、原理图

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

第一是能源减少原理图:

澳门太阳娱乐手机登录 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.随后就调用了 ResMinifier类里的 compressRes方法。在这里本人先附上 ResMinifier那个类的代码,然后方便一步步进展分析教学

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 能源压缩类 */ class ResMinifier { /** 供给减小的财富目录*/ public $compressResDir = ['css', 'js']; /** 忽略压缩的路线,比如此处是js/icon开端的门路忽略压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 财富根目录*/ public $resRootDir; /** 财富版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes() { //获取寄放版本的财富文件 $resState = $this->getResState(); $count = 0; //伊始遍历需求减少的能源目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该财富文件的相对路线$filePath = str_replace('\', '/', $file->getReal帕特h()); //获取文件相对路线 $object = substr($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);
    }
 
}
 
点击打开 资源压缩类

一切类超越50%代码小编都加了解说,方便大家飞快驾驭。这里笔者也会对每一行代码实行分解。

(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) { //获取能源相对路线 $filePath = $this->resRootDir . $object; //判别财富是不是留存 if (!file_exists($filePath)) return "能源文件空头支票{$filePath}"; //版本号 $state = $this-> _getResStateVersion($file帕特h); //文件名后缀 $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($file帕特h, $minFilePath);

先看$this->compressResFileAndSave()

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

PHP

/** * 将缩减后的财富文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFile帕特h}战败"); 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模板引擎================================// /* 斯马特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_DILAND.'Smarty.class.php'; $this->smarty = new 斯马特y(); $this->smarty->setCompileDir(应用软件PATH . 'cache/'); $this->smarty->setCacheDir(应用软件PATH . 'cache/'); } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } } /** * 能源路线 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; } private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) { if ('/' === $viewName[0]) $viewName = substr($viewName, 1); //是不是选拔模板,有,则路由到 /views/master_page/*****.tpl下去 if ($masterPage) { $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage); } //是还是不是设置模板目录 if ($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_DIPAJERO.'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模板引擎的情节,那几个关于斯马特y的文化作者就不讲了,我们可以谐和百度,这里主要讲 res_link() 这些函数,便是经过那么些函数来举办财富文件替换的。先看那一个函数的代码:

PHP

/** * 输出 HttpHead 中的财富总是。 css/js 自动推断真实路线 * @param string 文件路线 * @return string */ function res_link($file) { $file = res_path($file, $extension); if ($extension === 'css') { return '<link rel="stylesheet" type="text/css" href="' . $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 APPPATH.'libraries/ResMinifier.php'; $resminifier = new ResMinifier(); //获取寄放财富版本的文件的数组变量 $resState = $resminifier->getResState(); //计算取伏贴前文件版本号 $state = $resminifier->_getResStateVersion($filepath); //剖断该版本号是或不是留存 if (isset($resState[$object])) { //判别是还是不是是.min.css或.min.js结尾 if (str_end_with($object, '.min.'.$extension)) { //将版本号拼接上去,然后拿走min的文本路线 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension; } else { //将版本号拼接上去,然后拿走min的文书路线 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; } //决断min的门路是不是留存在$resState里面 if (isset($resState[$minObject])) { $object = $minObject; $query = ''; } } } $file = RES_BASE_URL . $object; } return ($query == null) ? $file : ($file .'?'. $query); }

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

代码基本上都给了批注,方便大家轻便去领略,前边一部分是智能路径css、js能源的不二法门,后边一部分是替换压缩版本,这一有个其他逻辑其实和能源收缩这里的逻辑基本一致,便是通过财富文件路线,举办决断和管理,最终收获财富的回降版本的渠道,最终就将财富的减少版本的门道重回去,放在'<link rel=”stylesheet” type=”text/css” href=”‘ . $file . ‘”/>’里面。那样  ,就成功地将财富文件路线替换来了减弱版本的能源文件路径,并且在模板输出时,输出的是降低后的能源文件。

到此,财富替换的开始和结果就到此疏解甘休。而整一项技能也深入分析到此。

三、总结

在那边自个儿集中地附着本博文疏解中的多少个公文代码:

Home.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Home extends MY_Controller { public function index() { $this->smartyData['test'] = 111; //这几个默许是加载 www/css/home/index.css文件 $this->addResLink('index.css'); //那一个默许是加载www/js/jquery.all.min.js文件 $this->addResLink('/jquery.all.min.js'); //这几个默许是加载www/js/index.js文件 $this->addResLink('index.js'); $this->displayView('home/index.tpl'); } } 点击张开

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

My_Controller.php

PHP

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

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

ResMinifier.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 能源压缩类 */ class ResMinifier { /** 须求减小的财富目录*/ public $compressResDir = ['css', 'js']; /** 忽略压缩的门路,比方此处是js/icon伊始的不二法门忽略压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 财富根目录*/ public $resRootDir; /** 能源版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes() { //获取存放版本的能源文件 $resState = $this->getResState(); $count = 0; //开端遍历供给减小的能源目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该能源文件的相对路径$filePath = str_replace('\', '/', $file->getRealPath()); //获取文件相对路线 $object = substr($filePath, strlen($this->resRootDir)); //计算文件的本子号 $state = $this->_getResStateVersion($filePath); //获取文件的几个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; } //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p推断是最重大片段之一*****************// //剖断文件是或不是存在且已经转移过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFile帕特h)) { 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 应用程式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端,假若是小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();

?>

本文由澳门太阳娱乐手机登录发布于公司简介,转载请注明出处:重型网址优化技能,php多文件上传

关键词: