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

静态资源文件自动削减并替换成压缩版本(大型网站优化技术)

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

初稿出处: Kelly   

这一回,我总括和享用一项大型网站优化技术,那就是在项目中活动削减静态资源文件(css、js),并让网站活动加载压缩后的资源文件。当然,那项技艺在雅虎35条前端优化提出里也有记载,但它那只是给出一个理论的方案而已,并且使用的是表面压缩工具去减弱,而在自家的门类中,是一直通过祥和的程序自动化去减弱所有css、js文件,然后让页面一贯加载所缩小后的资源,接下去直接进入正题。

此次实验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的条件(网上搭建无论是搭建LAMP如故LNMP的课程都五花八门一塌糊涂,下次我会总括和享用怎么样在LINUX下搭建服务器环境的博文,而且搭建的条件必须三回性搭建成功的)。所选取的框架是CI框架,所使用的模版是Smarty模板引擎。当然了,那些只是本身所利用的环境而已,若是您是PHP开发者,即使你要测试下这一次试验,那么,我提出您的PHP版本采取5.4以上,至于框架用怎么着都是能够的。而只要您不是PHP开发者(你是JSP或者是ASP开发者或者是其他开发者),那么您领悟好这一思路后,完全可以在团结深谙的言语里开展实验测试。

一、原理图

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

率先是资源裁减原理图:

亚洲必赢官网 1

继之是资源文件替换的原理图:

亚洲必赢官网 2

如若大家认真精晓并且看懂那两张原理图的话,基本上也就明白了自家所享用的思绪。借使如故不能精晓的话,接下去我会结合代码,对上述原理图的每一步进行详细讲解。

二、思路详细分析

1.先是是调用该滑坡的法子,你可以把该办法放在网站所要加载的公共类的地方,例如每趟访问网站都会调用该滑坡方法举办削减。当然,那几个只是在支付条件才会每便都调用,如果是线上的环境,在您的网站发两回新本子的时候,调用三次用来生成压缩版的静态资源就足以了。

静态资源文件自动削减并替换成压缩版本,生成html静态文件类程序与实例使用方式。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
\JShrink\Minifier::minify(file_get_contents($filePath)); } else if
($extension ===’css’) { $content = file_get_contents($filePath);
$content =
preg_replace(‘!/\*[^*]*\*+([^/][^*]*\*+)*/!’, ”,
$content); $content = str_replace([“\r\n”, “\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 =
“<?php\n\n\$resState = array(\n”; foreach ($resState as $k =>
$v) { $content .= “\t ‘$k’ => ‘$v’,\n”; } $content .= “);\n\n”;
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 \JShrink\Minifier::minify(file_get_contents($filePath));
        } else if ($extension ===’css’) {
            $content = file_get_contents($filePath);
            $content = preg_replace(‘!/\*[^*]*\*+([^/][^*]*\*+)*/!’, ”, $content);
            $content = str_replace(["\r\n", "\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 = "<?php\n\n\$resState = array(\n";
        foreach ($resState as $k => $v) {
            $content .= "\t ‘$k’ => ‘$v’,\n";
        }
        $content .= ");\n\n";
        file_put_contents($this->resStatePath, $content);
    }
 
}
 
点击打开 资源压缩类

全部类一大半代码我都加了诠释,方便大家火速了然。那里我也会对每一行代码进行表明。

(1)

PHP

/** 需要裁减的资源目录*/ public $compressResDir = [‘css’, ‘js’];
/** 忽略压缩的门径,例如此处是js/icon先导的门路忽略压缩*/ public
$compressResIngorePrefix = [‘js/icon’]; /** 资源根目录*/ public
$resRootDir; /** 资源版本文件路径*/ private $resStatePath; public
function __construct() { $this->resRootDir = WEBROOT . ‘www/’;
$this->resStatePath = WEBROOT . ‘www/resState.php’; }

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

$compressResDir变量是急需减小的资源目录,如若你有新的拍卖目录,可以在此变量里假诺新的目录名即可处理。附上自己测试项目标目录图

亚洲必赢官网 3

$compressResIngorePrefix 忽略被核减的不二法门的不二法门前有的是该数组变量的字符串,例如
有一个资源路径为
js/icon/bg.js或者是js/icon_index.js或者是js/icon.header.js,若是在该数组中参与了
js/icon那么些字符串,那么资源路径为js/icon起始的都会被忽视掉,也就是一贯跳过,不用压缩。(因为资源文件里总有一对是不要求减弱的嘛)

$resRootDir存放资源根目录的

$resStatePath 那些是资源版本文件路径

(2)进入compressRes() 方法,大家先分析前边这一段代码

PHP

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

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

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

此处首先是调用 $this->getResState() 方法来博取存放版本的资源文件,此处先跳到该格局看看是如何写的,其实就是包涵该文件,然后回来里面存放版本号的数组,大家看注释可以知道该文件里存放版本号的格式(顺便附上图让大家看看)

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($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
\JShrink\Minifier::minify(file_get_contents($filePath)); } else if
($extension ===’css’) { $content = file_get_contents($filePath);
$content =
preg_replace(‘!/\*[^*]*\*+([^/][^*]*\*+)*/!’, ”,
$content); $content = str_replace([“\r\n”, “\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 \JShrink\Minifier::minify(file_get_contents($filePath));
        } else if ($extension ===’css’) {
            $content = file_get_contents($filePath);
            $content = preg_replace(‘!/\*[^*]*\*+([^/][^*]*\*+)*/!’, ”, $content);
            $content = str_replace(["\r\n", "\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++的效率是,当那几个轮回50次就将
$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
= “<?php\n\n\$resState = array(\n”; foreach ($resState as $k
=> $v) { $content .= “\t ‘$k’ => ‘$v’,\n”; } $content .=
“);\n\n”; file_put_contents($this->resStatePath, $content); }

1
2
3
4
5
6
7
8
9
private function _saveResState($resState) {
        ksort($resState);
        $content = "<?php\n\n\$resState = array(\n";
        foreach ($resState as $k => $v) {
            $content .= "\t ‘$k’ => ‘$v’,\n";
        }
        $content .= ");\n\n";
        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_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

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

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

这一段代码没有一部分就是调用了Smarty模板引擎的始末,那一个关于Smarty的学识我就不讲了,大家可以自己百度,那里最首要讲
res_link()
这几个函数,就是经过那么些函数来开展资源文件替换的。先看这几个函数的代码:

PHP

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

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

此处最关键就是 res_path() 函数了,那个函数能半自动路由资源的真实性路径
。例如:index.css = > css/home/index.css

该函数最重点的一个效益是替换资源的削减版本。

一贯看代码:

PHP

/** * 智能路由资源实际路径 * @param string 路径 * @param string
扩展名 * @return string 真实路径 */ function res_path($file,
&$extension) { //检查是还是不是存在询问字符串 list($file, $query) =
explode(‘?’, $file . ‘?’); //取得扩张名 $extension =
strtolower(pathinfo($file, PATHINFO_EXTENSION)); // $file =
str_replace(‘\\’, ‘/’, $file); //取得当前控制器名 global $class; if
($class == null) exit(‘can not get class name’); $className =
strtolower($class); //此处的规则是这般: //例如,若是不加 /
,Home控制器对应的格式是: index.css,那么
此处的路径会变成css/home/index.css //如若有 / ,控制器的格式可以是
/main.css,那么那里的路径会变成 css/main.css(公用的css类) if (‘/’ !==
$file[0]) { //index.css => css/home/index.css $object = $extension
.’/’. $className .’/’ . $file; } else { // /css/main.css 或者 /main.css
=> css/main.css $object = substr($file, 1); //若object是 main.css
,则自动抬高 增加名目录 => css/main.css if (0 !==
strncasecmp($extension, $object, strlen($extension))) { $object =
$extension . ‘/’ . $object; } } //资源真实路径 $filepath =
WEBROOT.’www/’.$object; //替换压缩版本,这一部分逻辑与公事收缩逻辑对应 if
(in_array($extension, array(‘css’, ‘js’))) {
if(!str_start_with($object, ‘min/’) &&
file_exists(APPPATH.’libraries/ResMinifier.php’)) { require_once
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模板引擎================================//
/* 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(); } } 点击打开

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

ResMinifier.php

PHP

<?php defined(‘BASEPATH’) OR exit(‘No direct script access allowed’);
/** * 资源压缩类 */ class ResMinifier { /** 要求减小的资源目录*/
public $compressResDir = [‘css’, ‘js’]; /**
忽略压缩的门路,例如此处是js/icon起先的门道忽略压缩*/ public
$compressResIngorePrefix = [‘js/icon’]; /** 资源根目录*/ public
$resRootDir; /** 资源版本文件路径*/ private $resStatePath; public
function __construct() { $this->resRootDir = WEBROOT . ‘www/’;
$this->resStatePath = WEBROOT . ‘www/resState.php’; } public function
compressRes() { //获取存放版本的资源文件 $resState =
$this->getResState(); $count = 0; //发轫遍历要求减弱的资源目录
foreach ($this->compressResDir as $resDir) { foreach (new
RecursiveIteratorIterator(new
RecursiveDirectoryIterator($this->resRootDir . $resDir ,
FilesystemIterator::SKIP_DOTS)) as $file) { //获取该资源文件的相对路径
$filePath = str_replace(‘\\’, ‘/’, $file->getRealPath());
//获取文件相对路径 $object = substr($filePath,
strlen($this->resRootDir)); //计算文件的版本号 $state =
$this->_getResStateVersion($filePath); //获取文件的多少个参数值 if
(true !== $this->getObjectInfo($object, $minObject, $needCompress,
$state, $extension)) { continue; } //压缩文件的相对路径 $minFilePath =
str_replace(‘\\’, ‘/’, $this->resRootDir. $minObject);
//************此处p判断是最紧要片段之一*****************//
//判断文件是或不是留存且早已改成过 if (isset($resState[$object]) &&
$resState[$object] == $state && isset($resState[$minObject]) &&
file_exists($minFilePath)) { continue; } //确保/www/min/目录可写
$this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress)
{ $this->compressResFileAndSave($filePath, $minFilePath); } else {
copy($filePath, $minFilePath); } $resState[$object] = $state;
$resState[$minObject] = ”; $count++; if ($count == 50) {
$this->_saveResState($resState); $count = 0; } } } if($count)
$this->_saveResState($resState); } /** * 获取资源文件有关信息 *
@param [type] $object 资源文件路径 (www/css/home/index.css) * @param
[type] $minObject 压缩资源文件路径 (www/min/css/home/index.ae123a.css)
* @param [type] $needCompress 是或不是须要压缩 * @param [type] $state
文件版本号 * @param [type] $extension 文件名后缀 * @return [type]
[description] */ public function getObjectInfo($object, &$minObject,
&$needCompress, &$state, &$extension) { //获取资源相对路径 $filePath =
$this->resRootDir . $object; //判断资源是或不是存在 if
(!file_exists($filePath)) return “资源文件不存在{$filePath}”; //版本号
$state = $this-> _getResStateVersion($filePath); //文件名后缀
$extension = pathinfo($filePath, PATHINFO_EXTENSION); //是不是要减小
$needCompress = true; //判断资源文件是不是是以 .min.css或者.min.js结尾的
//此类结尾一般都是已缩减过,例如jquery.min.js,就不必再压缩了 if
(str_end_with($object, ‘.min.’.$extension, true)) {
//压缩后的资源存放路径,放在 /www/min/ 目录下 $minObject =
‘min/’.substr($object, 0, strlen($object) – strlen($extension) – 4) .
$state .’.’. $extension; $needCompress = false; } else if
(in_array($extension, $this->compressResDir)) {
//此处是内需收缩的文件目录 $minObject = ‘min/’.substr($object, 0,
strlen($object) – strlen($extension)) . $state . ‘.’ . $extension;
//看看是还是不是是忽略的门径前缀 foreach ($this->compressResIngorePrefix as
$v) { if (str_start_with($object, $v, true)) { $needCompress = false;
} } } else { $minObject = ‘min/’.$object; $needCompress = false; }
return true; } /** * 获取存放资源版本的公文 * 它是放在一个数组里 *
$resState = array( * ‘文件路径’ => ‘对应的本子号’, * ‘文件路径’
=> ‘对应的版本号’, * ‘文件路径’ => ‘对应的本子号’, * ); *
@return [type] [description] */ public function getResState() { if
(file_exists($this->resStatePath)) { require $this->resStatePath;
return $resState; } return []; } /** *
计算文件的本子号,那几个是基于统计文件MD5散列值得到版本号 *
只要文件内容改动了,所统计获得的散列值就会不相同 *
用于判断资源文件是不是有变动过 * @param [type] $filePath
[description] * @return [type] [description] */ public function
_getResStateVersion($filePath) { return
base_convert(crc32(md5_file($filePath)), 10, 36); } /** *
确保目录可写 * @param [type] $dir [description] * @return [type]
[description] */ private function _ensureWritableDir($dir) { if
(!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); }
else if (!is_writable($dir)) { @chmod($dir, 0777); if
(!is_writable($dir)) { show_error(‘目录’.$dir.’不可写’); } } } /**
* 将回落后的资源文件写入到/www/min/下去 * @param [type] $filePath
[description] * @param [type] $minFilePath [description] *
@return [type] [description] */ private function
compressResFileAndSave($filePath, $minFilePath) { if
(!file_put_contents($minFilePath,
$this->compressResFile($filePath))) {
//$CI->exceptions->show_exception(“写入文件{$minFilePath}战败”);
show_error(“写入文件{$minFilePath}失利”, -1); } } /** * 压缩资源文件
* @param [type] $filePath [description] * @return [type]
[description] */ private function compressResFile($filePath) {
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if
($extension === ‘js’) { require_once ‘JShrink/Minifier.php’; return
\JShrink\Minifier::minify(file_get_contents($filePath)); } else if
($extension ===’css’) { $content = file_get_contents($filePath);
$content =
preg_replace(‘!/\*[^*]*\*+([^/][^*]*\*+)*/!’, ”,
$content); $content = str_replace([“\r\n”, “\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 =
“<?php\n\n\$resState = array(\n”; foreach ($resState as $k =>
$v) { $content .= “\t ‘$k’ => ‘$v’,\n”; } $content .= “);\n\n”;
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 \JShrink\Minifier::minify(file_get_contents($filePath));
        } else if ($extension ===’css’) {
            $content = file_get_contents($filePath);
            $content = preg_replace(‘!/\*[^*]*\*+([^/][^*]*\*+)*/!’, ”, $content);
            $content = str_replace(["\r\n", "\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 = "<?php\n\n\$resState = array(\n";
        foreach ($resState as $k => $v) {
            $content .= "\t ‘$k’ => ‘$v’,\n";
        }
        $content .= ");\n\n";
        file_put_contents($this->resStatePath, $content);
    }
 
}
 
点击打开

Common.php

PHP

<?php /** * 输出 HttpHead 中的资源总是。 css/js 自动判断真实路径
* @param string 文件路径 * @return string */ function
res_link($file) { $file = res_path($file, $extension); if ($extension
=== ‘css’) { return ‘<link rel=”stylesheet” type=”text/css” href=”‘ .
$file . ‘”/>’; } else if ($extension === ‘js’) { return ‘<script
type=”text/javascript” src=”‘.$file.'”></script>’; } else {
return false; } } /** * 智能路由资源实际路径 * @param string 路径 *
@param string 扩展名 * @return string 真实路径 */ function
res_path($file, &$extension) { //检查是不是留存询问字符串 list($file,
$query) = explode(‘?’, $file . ‘?’); //取得扩充名 $extension =
strtolower(pathinfo($file, PATHINFO_EXTENSION)); // $file =
str_replace(‘\\’, ‘/’, $file); //取得当前控制器名 global $class; if
($class == null) exit(‘can not get class name’); $className =
strtolower($class); //此处的条条框框是如此: //例如,借使不加 /
,Home控制器对应的格式是: index.css,那么
此处的路径会变成css/home/index.css //要是有 / ,控制器的格式可以是
/main.css,那么那里的路径会变成 css/main.css(公用的css类) if (‘/’ !==
$file[0]) { //index.css => css/home/index.css $object = $extension
.’/’. $className .’/’ . $file; } else { // /css/main.css 或者 /main.css
=> css/main.css $object = substr($file, 1); //若object是 main.css
,则自动抬高 扩充名目录 => css/main.css if (0 !==
strncasecmp($extension, $object, strlen($extension))) { $object =
$extension . ‘/’ . $object; } } //资源真实路径 $filepath =
WEBROOT.’www/’.$object; //替换压缩版本,这一部分逻辑与公事缩短逻辑对应 if
(in_array($extension, array(‘css’, ‘js’))) {
if(!str_start_with($object, ‘min/’) &&
file_exists(APPPATH.’libraries/ResMinifier.php’)) { require_once
APPPATH.’libraries/ResMinifier.php’; $resminifier = new ResMinifier();
//获取存放资源版本的文件的数组变量 $resState =
$resminifier->getResState(); //总结取得当前文件版本号 $state =
$resminifier->_getResStateVersion($filepath); //判断该版本号是还是不是留存
if (isset($resState[$object])) { //判断是不是是.min.css或.min.js结尾 if
(str_end_with($object, ‘.min.’.$extension)) {
//将版本号拼接上去,然后拿走min的文本路径 $minObject =
‘min/’.substr($object, 0, strlen($object) – strlen($extension) – 4) .
$state . ‘.’ . $extension; } else {
//将版本号拼接上去,然后拿走min的文件路径 $minObject =
‘min/’.substr($object, 0, strlen($object) – strlen($extension)) . $state
. ‘.’ . $extension; } //判断min的门径是或不是存在在$resState里面 if
(isset($resState[$minObject])) { $object = $minObject; $query = ”; }
} } $file = RES_BASE_URL . $object; } return ($query == null) ? $file
: ($file .’?’. $query); } /** * 判断 subject 是或不是以 search伊始,
参数指定是不是忽略大小写 * @param [type] $subject [description] *
@param [type] $search [description] * @param boolean $ignore_case
[description] * @return [type] [description] */ function
str_start_with($subject, $search, $ignore_case = false) { $len2 =
strlen($search); if (0 === $len2) return true; $len1 = strlen($subject);
if ($len1 < $len2) return false; if ($ignore_case) { return 0 ===
strncmp($subject, $search, $len2); } else { return 0 ===
strncasecmp($subject, $search, $len2); } } /** * 判断 subject 是不是以
search结尾, 参数指定是不是忽略大小写 * @param [type] $subject
[description] * @param [type] $search [description] * @param
boolean $ignore_case [description] * @return [type]
[description] */ function str_end_with($subject, $search,
$ignore_case = false) { $len2 = strlen($search); if (0 === $len2)
return true; $len1 = strlen($subject); if ($len2 > $len1) return
false; if ($ignore_case) { return 0 === strcmp(substr($subject, $len1 –
$len2), $search); } else { return 0 === strcasecmp(substr($subject,
$len1 – $len2), $search); } } 点击打开

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

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

XHTML

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

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

 

除此以外附上JShrink这几个PHP类的链接给大家下载 

万一大家仍然认为不够OK的话,我一贯将以此实验项目打包供大家下载下来学习和询问:

四、结语

终极自己来享受大家线上项目标切切实实贯彻方案:

咱俩的门类分线上环境、开发环境和测试环境,在支付和测试环境中,大家每便访问都会调用压缩文件的接口,然后再对转移的资源文件的大大小小是要做判定的,要是缩减后文件过小,就须求将该资源文件的代码合并到其它资源文件里去,以此减弱不要求的HTTP请求(因为文件太小,资源的下载时间远远小于HTTP请求响应所开支的大运);另一个是图表的处理,所有图片都要透过压缩才能透过(例如在: 
这些网站去缩小图片),在PC端,假使是小图标的话,使用图片合并的主意举办优化,详情可参照本人的那篇博文:http://www.cnblogs.com/it-cen/p/4618954.html   
而在wap端的图形处理利用的是base64编码方式来处理图片,详情可以参见本人的这篇博文: 
,当页面输出时,会采取redis来缓存页面(为什么用内存来缓存而不是使用页面缓存,那个以后再享受给我们)。倘使是线上环境,每发几遍版本,才会调用一下资源文件减弱这么些接口,并且线上的静态资源(css、js、图片)是存放在在阿里云的OSS里的,与我们的应用服务器是分其余。那是我们线上项目标一部分优化解决方案,当然了,还有更加多优化技术,我会在其后各类计算和分享出去,方便大家一齐上学和互换。

此次博文就享受到此,谢谢观察此博文的仇敌们。

1 赞 1 收藏
评论

亚洲必赢官网 7

文件上传例子

class html
{
var $dir; //dir for the htmls(without/)
var $rootdir; //root of html files(without/):html
var $name; //html文件存放路径
var $dirname; //指定的文书夹名称
var $url; //获取html文件新闻的来源网页地址
var $time; //html文件消息填加时的岁月
var $dirtype; //目录存放方式:year,month,,,,
var $nametype; //html文件命名方式:name

此间是来源于网络朋友的一个兑现的文件上传类代码,大家详细的牵线了每个变量的用途,上边看看吧,有须要可以参考一下。

 代码如下

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

<?php教程
 /**
  * 文件上传类
  */
 class uploadFile {

  public $max_size = ‘1000000’;//设置上传文件大小
  public $file_name =
‘date’;//重命超级模特式表示以时间命名,其余则选择予以的称谓
  public $allow_types;//允许上传的文本扩充名,不一致文件类型用“|”隔开
  public $errmsg = ”;//错误音讯
  public $uploaded = ”;//上传后的公文名(包涵文件路径)
  public $save_path;//上传文件保留路径
  private $files;//提交的等待上传文件
  private $file_type = array();//文件类型
  private $ext = ”;//上传文件增添名

  /**
   * 构造函数,伊始化类
   * @access public
   * @param string $file_name 上传后的文书名
   * @param string $save_path 上传的目的文件夹
   */
  public function __construct($save_path = ‘./upload/’,$file_name
= ‘date’,$allow_types = ”) {
  $this->file_name   =
$file_name;//重命名形式意味着以时间命名,其他则动用予以的称谓
  $this->save_path   =
(preg_match(‘//$/’,$save_path))
? $save_path : $save_path . ‘/’;
  $this->allow_types = $allow_types == ” ? ‘jpg|gif|png|zip|rar’
: $allow_types;
  }

  /**
   * 上传文件
   * @access public
   * @param $files 等待上传的文本(表单传来的$_FILES[])
   * @return boolean 再次来到布尔值
   */
 public function upload_file($files) {
  $name = $files[‘name’];
  $type = $files[‘type’];
  $size = $files[‘size’];
  $tmp_name = $files[‘tmp_name’];
  $error = $files[‘error’];

  switch ($error) {
   case 0 : $this->errmsg = ”;
    break;
   case 1 : $this->errmsg = ‘超越了php.ini汉语件大小’;
    break;
   case 2 : $this->errmsg = ‘超过了MAX_FILE_SIZE
选项指定的文书大小’;
    break;
       case 3 : $this->errmsg = ‘文件唯有部分被上传’;
    break;
   case 4 : $this->errmsg = ‘没有公文被上传’;
    break;
   case 5 : $this->errmsg = ‘上传文件大小为0’;
    break;
      default : $this->errmsg = ‘上传文件败北!’;
    break;
   }
  if($error == 0 && is_uploaded_file($tmp_name)) {
   //检测文件类型
   if($this->check_file_type($name) == FALSE){
    return FALSE;
   }
   //检测文件大小
   if($size > $this->max_size){
    $this->errmsg = ‘上传文件<font
color=red>’.$name.'</font>太大,最大扶助<font
color=red>’.ceil($this->max_size/1024).'</font>kb的文件’;
    return FALSE;
   }
   $this->set_save_path();//设置文件存放路径
   $new_name = $this->file_name != ‘date’ ?
$this->file_name.’.’.$this->ext :
date(‘YmdHis’).’.’.$this->ext;//设置新文件名
   $this->uploaded =
$this->save_path.$new_name;//上传后的文本名
   //移动文件
   if(move_uploaded_file($tmp_name,$this->uploaded)){
    $this->errmsg = ‘文件<font
color=red>’.$this->uploaded.'</font>上传成功!’;
    return TRUE;
   }else{
    $this->errmsg = ‘文件<font
color=red>’.$this->uploaded.'</font>上传失利!’;
    return FALSE;
   }

  }
 }

  /**
   * 检查上传文件类型
   * @access public
   * @param string $filename 等待检查的文本名
   * @return 如若检查通过重回TRUE 未通过则赶回FALSE和不当音讯
   */
    public function check_file_type($filename){
  $ext = $this->get_file_type($filename);
  $this->ext = $ext;
    $allow_types =
explode(‘|’,$this->allow_types);//分割允许上传的公文增添名为数组
    //echo $ext;
    //检查上传文件伸张名是否在请允许上传的文本扩大名中
    if(in_array($ext,$allow_types)){
     return TRUE;
    }else{
     $this->errmsg = ‘上传文件<font
color=red>’.$filename.'</font>类型错误,只接济上传<font
color=red>’.str_replace(‘|’,’,’,$this->allow_types).'</font>等文件类型!’;
     return FALSE;
    }
    }

    /**
     * 取得文件类型
     * @access public
     * @param string $filename 要收获文件类型的目的文件名
     * @return string 文件类型
     */
    public function get_file_type($filename){
     $info = pathinfo($filename);
     $ext = $info[‘extension’];
     return $ext;
    }

 /**
  * 设置文件上传后的保留路径
  */
 public function set_save_path(){
  $this->save_path = (preg_match(‘//$/’,$this->save_path)) ?
$this->save_path : $this->save_path . ‘/’;
  if(!is_dir($this->save_path)){
   //即使目录不设有,制造目录
   $this->set_dir();
  }
 }

 /**
  * 创建目录
  * @access public
  * @param string $dir 要开创目录的途径
  * @return boolean 失利时回来错误音信和FALSE
  */
 public function set_dir($dir = null){
  //检查路径是不是存在
  if(!$dir){
   $dir = $this->save_path;
  }
  if(is_dir($dir)){
   $this->errmsg = ‘须要创立的文本夹已经存在!’;
  }
  $dir = explode(‘/’, $dir);
  foreach($dir as $v){
   if($v){
    $d .= $v . ‘/’;
    if(!is_dir($d)){
     $state = mkdir($d, 0777);
     if(!$state)
      $this->errmsg = ‘在开立目录<font color=red>’ . $d .
‘时出错!’;
    }
   }
  }
  return true;
 }
 }

/*************************************************
 * 图片处理类
 *
 *
可以对图纸展开变更缩略图,打水印等操作
 * 本类默许编码为UTF8
假诺要在GBK下利用请将img_mark方法中打中文字符串水印iconv诠释去掉
 *
 *
由于UTF8汉字和英文字母大小(像素)不好确定,在中国和英国文混合出现太多时或许见面世字符串偏左
 * 或偏右,请根据项目条件对get_mark_xy方法中的$strc_w =
strlen($this->mark_str)*7+5进
 * 行调整
 * 需求GD库支持,为更好使用本类推荐使用GD库2.0+
 *
 * @author kickflip@php100 QQ263340607
 *************************************************/

 class uploadImg extends uploadFile {

 public $mark_str =
‘kickflip@php100’; 
//水印字符串
 public $str_r = 0; //字符串颜色R
 public $str_g = 0; //字符串颜色G
 public $str_b = 0; //字符串颜色B
 public $mark_ttf = ‘./upload/SIMSUN.TTC’;
//水印文字字体文件(包蕴路径)
 public $mark_logo = ‘./upload/logo.png’;    //水印图片
 public $resize_h;//生成缩略图高
 public $resize_w;//生成缩略图宽
 public $source_img;//源图片文件
 public $dst_path =
‘./upload/’;//缩略图文件存放目录,不填则为源图片存放目录

 /**
  * 生成缩略图 生成后的图
  * @access public
  * @param integer $w 减少后图片的宽(px)
  * @param integer $h 缩短后图片的高(px)
  * @param string $source_img 源图片(路径+文件名)
  */
 public function img_resized($w,$h,$source_img = NULL){
  $source_img = $source_img == NULL ? $this->uploaded :
$source_img;//取得源文件的地方,若是为空则默认为上次上传的图样
  if(!is_file($source_img)) { //检查源图片是不是留存
   $this->errmsg = ‘文件’.$source_img.’不存在’;
   return FALSE;
  }
  $this->source_img = $source_img;
  $img_info = getimagesize($source_img);
  $source = $this->img_create($source_img); //创建源图片
  $this->resize_w = $w;
  $this->resize_h = $h;
  $thumb = imagecreatetruecolor($w,$h);
  imagecopyresized($thumb,$source,0,0,0,0,$w,$h,$img_info[0],$img_info[1]);//生成缩略图片
  $dst_path = $this->dst_path == ” ? $this->save_path :
$this->dst_path; //取得目的文件夹路径
  $dst_path = (preg_match(‘//$/’,$dst_path)) ? $dst_path :
$dst_path . ‘/’;//将对象文件夹后增进/
  if(!is_dir($dst_path)) $this->set_dir($dst_path);
//要是不存在目标文件夹则成立
  $dst_name = $this->set_newname($source_img);
  $this->img_output($thumb,$dst_name);//输出图片
  imagedestroy($source);
  imagedestroy($thumb);
 }

 /**
  *打水印
  *@access public
  *@param string $source_img 源图片路径+文件名
  *@param integer $mark_type
水印类型(1为英文字符串,2为中文字符串,3为图片logo,默许为英文字符串)
  *@param integer $mark_postion
水印地方(1为左下角,2为右下角,3为左上角,4为右上角,默许为右下角);
  *@return 打上水印的图片
  */
 public function img_mark($source_img = NULL,$mark_type =
1,$mark_postion = 2) {
  $source_img = $source_img == NULL ? $this->uploaded :
$source_img;//取得源文件的地点,假设为空则默许为上次上传的图样
  if(!is_file($source_img)) { //检查源图片是还是不是存在
   $this->errmsg = ‘文件’.$source_img.’不存在’;
   return FALSE;
  }
  $this->source_img = $source_img;
  $img_info = getimagesize($source_img);
  $source = $this->img_create($source_img); //创设源图片
  $mark_xy = $this->get_mark_xy($mark_postion);//取得水印地点
  $mark_color =
imagecolorallocate($source,$this->str_r,$this->str_g,$this->str_b);

  switch($mark_type) {

   case 1 : //加英文字符串水印
   $str = $this->mark_str;
   imagestring($source,5,$mark_xy[0],$mark_xy[1],$str,$mark_color);
   $this->img_output($source,$source_img);
   break;

            case 2 : //加汉语字符串水印
            if(!is_file($this->mark_ttf)) {
//检查字体文件是不是存在
    $this->errmsg =
‘打水印失利:字体文件’.$this->mark_ttf.’不存在!’;
   return FALSE;
   }
   $str = $this->mark_str;
   //$str = iconv(‘gbk’,’utf-8′,$str);//转换字符编码
若是利用GBK编码请去掉此行注释
   imagettftext($source,12,0,$mark_xy[2],$mark_xy[3],$mark_color,$this->mark_ttf,$str);
   $this->img_output($source,$source_img);
   break;

   case 3 : //加图片水印
   if(is_file($this->mark_logo)){ 
//假诺存在水印logo的图样则得到logo图片的着力音信,不存在则脱离
    $logo_info = getimagesize($this->mark_logo);
   }else{
    $this->errmsg =
‘打水印战败:logo文件’.$this->mark_logo.’不存在!’;
    return FALSE;
   }

   $logo_info = getimagesize($this->mark_logo);
   if($logo_info[0]>$img_info[0] ||
$logo_info[1]>$img_info[1]) {
//假若源图片小于logo大小则脱离
    $this->errmsg =
‘打水印战败:源图片’.$this->source_img.’比’.$this->mark_logo.’小!’;
    return FALSE;
   }

   $logo = $this->img_create($this->mark_logo);
   imagecopy ( $source, $logo, $mark_xy[4], $mark_xy[5], 0, 0,
$logo_info[0], $logo_info[1]);
   $this->img_output($source,$source_img);
   break;

   default: //其余则为文字图片
   $str = $this->mark_str;
   imagestring($source,5,$mark_xy[0],$mark_xy[1],$str,$mark_color);
   $this->img_output($source,$source_img);
   break;
  }
  imagedestroy($source);
 }

 /**
  * 取得水印地点
  * @access private
  * @param integer $mark_postion
水印的职责(1为左下角,2为右下角,3为左上角,4为右上角,其余为右下角)
  * @return array $mark_xy
水印地方的坐标(索引0为英文字符串水印坐标X,索引1为英文字符串水印坐标Y,
  *
索引2为粤语字符串水印坐标X,索引3为普通话字符串水印坐标Y,索引4为水印图片坐标X,索引5为水印图片坐标Y)
  */
 private function get_mark_xy($mark_postion){
  $img_info = getimagesize($this->source_img);

  $stre_w = strlen($this->mark_str)*9+5 ;
//水印英文字符串的长短(px)(5号字的英文字符大小约为9px
为了雅观再加5px)
  //(12号字的国语字符大小为12px,在utf8里一个中国字长度为3个字节一个字节4px
而一个英文字符长度一个字节大小几乎为9px
  // 为了在中国和英国文混合的场馆下显得完全 设它的长短为字节数*7px)
  $strc_w = strlen($this->mark_str)*7+5 ;
//水印粤语字符串的尺寸(px)

  if(is_file($this->mark_logo)){
//若是存在水印logo的图片则赢得logo图片的着力音讯
   $logo_info = getimagesize($this->mark_logo);
  }

  //由于imagestring函数和imagettftext函数中对此字符串初叶地方不相同所以英文和中文字符串的Y地点也黯然失色
  //imagestring函数是从文字的左上角为参照
imagettftext函数是从文字左下角为参照
  switch($mark_postion){

   case 1: //地点左下角
   $mark_xy[0] = 5; //水印英文字符串坐标X
   $mark_xy[1] = $img_info[1]-20;//水印英文字符串坐标Y
   $mark_xy[2] = 5; //水印中文字符串坐标X
   $mark_xy[3] = $img_info[1]-5;//水印粤语字符串坐标Y
   $mark_xy[4] = 5;//水印图片坐标X
   $mark_xy[5] =
$img_info[1]-$logo_info[1]-5;//水印图片坐标Y
   break;

   case 2: //地点右下角
   $mark_xy[0] = $img_info[0]-$stre_w; //水印英文字符串坐标X
   $mark_xy[1] = $img_info[1]-20;//水印英文字符串坐标Y
   $mark_xy[2] = $img_info[0]-$strc_w; //水印粤语字符串坐标X
   $mark_xy[3] = $img_info[1]-5;//水印汉语字符串坐标Y
   $mark_xy[4] =
$img_info[0]-$logo_info[0]-5;//水印图片坐标X
   $mark_xy[5] =
$img_info[1]-$logo_info[1]-5;//水印图片坐标Y
   break;

   case 3: //地点左上角
   $mark_xy[0] = 5; //水印英文字符串坐标X
   $mark_xy[1] = 5;//水印英文字符串坐标Y
   $mark_xy[2] = 5; //水印中文字符串坐标X
   $mark_xy[3] = 15;//水印中文字符串坐标Y
   $mark_xy[4] = 5;//水印图片坐标X
   $mark_xy[5] = 5;//水印图片坐标Y
   break;

   case 4: //地方右上角
   $mark_xy[0] = $img_info[0]-$stre_w; //水印英文字符串坐标X
   $mark_xy[1] = 5;//水印英文字符串坐标Y
   $mark_xy[2] = $img_info[0]-$strc_w; //水印中文字符串坐标X
   $mark_xy[3] = 15;//水印汉语字符串坐标Y
   $mark_xy[4] =
$img_info[0]-$logo_info[0]-5;//水印图片坐标X
   $mark_xy[5] = 5;//水印图片坐标Y
   break;

   default : //其它默许为右下角
   $mark_xy[0] = $img_info[0]-$stre_w; //水印英文字符串坐标X
   $mark_xy[1] = $img_info[1]-5;//水印英文字符串坐标Y
   $mark_xy[2] = $img_info[0]-$strc_w; //水印汉语字符串坐标X
   $mark_xy[3] = $img_info[1]-15;//水印普通话字符串坐标Y
   $mark_xy[4] =
$img_info[0]-$logo_info[0]-5;//水印图片坐标X
   $mark_xy[5] =
$img_info[1]-$logo_info[1]-5;//水印图片坐标Y
   break;
  }
  return $mark_xy;
 }

 /**
  * 创设源图片
  * @access private
  * @param string $source_img 源图片(路径+文件名)
  * @return img 从目的文件新建的图像
  */
 private function img_create($source_img) {
  $info = getimagesize($source_img);
  switch ($info[2]){
            case 1:
            if(!function_exists(‘imagecreatefromgif’)){
             $source = @imagecreatefromjpeg($source_img);
            }else{
             $source = @imagecreatefromgif($source_img);
            }
            break;
            case 2:
            $source = @imagecreatefromjpeg($source_img);
            break;
            case 3:
            $source = @imagecreatefrompng($source_img);
            break;
            case 6:
            $source = @imagecreatefromwbmp($source_img);
            break;
            default:
   $source = FALSE;
   break;
        }
  return $source;
 }

 /**
  * 重命名图片
  * @access private
  * @param string $source_img 源图片路径+文件名
  * @return string $dst_name 重命名后的图纸名(路径+文件名)
  */
 private function set_newname($sourse_img) {
  $info = pathinfo($sourse_img);
  $new_name =
$this->resize_w.’_’.$this->resize_h.’_’.$info[‘basename’];//将文件名修改为:宽_高_文件名
  if($this->dst_path == ”){
//如若存放缩略图路径为空则默许为源文件同文件夹
   $dst_name =
str_replace($info[‘basename’],$new_name,$sourse_img);
  }else{
   $dst_name = $this->dst_path.$new_name;
  }
  return $dst_name;
 }

 /**
  * 输出图片
  * @access private
  * @param $im 处理后的图纸
  * @param $dst_name 输出后的的图样名(路径+文件名)
  * @return 输出图片
  */
 public function img_output($im,$dst_name) {
  $info = getimagesize($this->source_img);
  switch ($info[2]){
            case 1:
            if(!function_exists(‘imagegif’)){
             imagejpeg($im,$dst_name);
            }else{
             imagegif($im, $dst_name);
            }
            break;
            case 2:
            imagejpeg($im,$dst_name);
            break;
            case 3:
            imagepng($im,$dst_name);
            break;
            case 6:
            imagewbmp($im,$dst_name);
            break;
        }
 }

 }
?>

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

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

其一写成了上传文件类就方便多了,把上边代码保存一个文本它就可以共用调用与修改删除了。

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

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

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

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

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

}
}
}

?>

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

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

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

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

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

文本上传类代码

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

 代码如下

$this->createdir();

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

return $this->dir;
}

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

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

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

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

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

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

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

}
return $this->name;
}

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

function createhtml($url=”,$time=0,$dirname=”,$htmlname=”)
{
$this->url=$url?$url:$this->url;
$this->dirname=$dirname?$dirname:$this->dirname;
$this->time=$time?$time:$this->time;
//下边有限援助不另行地把变量赋予该类成员
if(empty($htmlname))
$this->getname();
else
$this->name=$dirname.’/’.$htmlname; //得到name

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

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

return count($this->save_info);
}

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

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

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

return TRUE;
}

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

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

$this->getname();

return FALSE;
}

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

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

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

return $p[‘extension’];
}

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

/*
 *赢得文件名(不包涵增添名)
 *
 *@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();

?>

网站地图xml地图