php多文件上传,文件上传类代码

by admin on 2019年2月12日

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

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开发者只怕是其余开发者),那么你知道好这一思路后,完全可以在友好深谙的语言里展开尝试测试。

一、原理图

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

率先是资源裁减原理图:

必发88 1

跟着是资源文件替换的规律图:

必发88 2

若是大家认真明白并且看懂那两张原理图的话,基本上也就控制了我所享用的笔触。假使如故不可以明白的话,接下去我会结合代码,对上述原理图的每一步举行详尽讲解。

二、思路详细分析

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

class MY_Controller extends CI_Controller { public function
__construct() { parent::__construct(); //压缩jscss资源文件
$this->compressResHandle(); } /** * 压缩js、css资源文件(优化) *
@return [type] [description] */ private function
compressResHandle() { $this->load->library(‘ResMinifier’);
//压缩指定文件夹下的资源文件 $this->resminifier->compressRes(); }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library(‘ResMinifier’);
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}

2.接着就调用了 ResMinifier类里的 compressRes方法。在此间我先附上
ResMinifier那些类的代码,然后方便一步步拓展辨析教学

PHP

<?php defined(‘BASEPATH’) OR exit(‘No direct script access allowed’);
/** * 资源压缩类 */ class ResMinifier { /** 须要裁减的资源目录*/
public $compressResDir = [‘css’, ‘js’]; /**
忽略压缩的门径,例如此处是js/icon先导的门路忽略压缩*/ public
$compressResIngorePrefix = [‘js/icon’]; /** 资源根目录*/ public
$resRootDir; /** 资源版本文件路径*/ private $resStatePath; public
function __construct() { $this->resRootDir = WEBROOT . ‘www/’;
$this->resStatePath = WEBROOT . ‘www/resState.php’; } public function
compressRes() { //获取存放版本的资源文件 $resState =
$this->getResState(); $count = 0; //开端遍历需求减小的资源目录
foreach ($this->compressResDir as $resDir) { foreach (new
RecursiveIteratorIterator(new
RecursiveDirectoryIterator($this->resRootDir . $resDir ,
FilesystemIterator::SKIP_DOTS)) as $file) { //获取该资源文件的相对路径
$filePath = str_replace(‘\\’, ‘/’, $file->getRealPath());
//获取文件相对路径 $object = substr($filePath,
strlen($this->resRootDir)); //总结文件的本子号 $state =
$this->_getResStateVersion($filePath); //获取文件的多少个参数值 if
(true !== $this->getObjectInfo($object, $minObject, $needCompress,
$state, $extension)) { continue; } //压缩文件的相对路径 $minFilePath =
str_replace(‘\\’, ‘/’, $this->resRootDir. $minObject);
//************此处p判断是最关键片段之一*****************//
//判断文件是或不是留存且早已变更过 if (isset($resState[$object]) &&
$resState[$object] == $state && isset($resState[$minObject]) &&
file_exists($minFilePath)) { continue; } //确保/www/min/目录可写
$this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress)
{ $this->compressResFileAndSave($filePath, $minFilePath); } else {
copy($filePath, $minFilePath); } $resState[$object] = $state;
$resState[$minObject] = ”; $count++; if ($count == 50) {
$this->_saveResState($resState); $count = 0; } } } if($count)
$this->_saveResState($resState); } public function
getObjectInfo($object, &$minObject, &$needCompress, &$state,
&$extension) { //获取资源相对路径 $filePath = $this->resRootDir .
$object; //判断资源是还是不是留存 if (!file_exists($filePath)) return
“资源文件不设有{$filePath}”; //版本号 $state = $this->
_getResStateVersion($filePath); //文件名后缀 $extension =
pathinfo($filePath, PATHINFO_EXTENSION); //是还是不是要收缩 $needCompress =
true; //判断资源文件是或不是是以 .min.css或许.min.js结尾的
//此类结尾一般都以已压缩过,例如jquery.min.js,就不用再压缩了 if
(str_end_with($object, ‘.min.’.$extension, true)) {
//压缩后的资源存放路径,放在 /www/min/ 目录下 $minObject =
‘min/’.substr($object, 0, strlen($object) – strlen($extension) – 4) .
$state .’.’. $extension; $needCompress = false; } else if
(in_array($extension, $this->compressResDir)) {
//此处是需求减小的文件目录 $minObject = ‘min/’.substr($object, 0,
strlen($object) – strlen($extension)) . $state . ‘.’ . $extension;
//看看是或不是是忽略的不二法门前缀 foreach ($this->compressResIngorePrefix as
$v) { if (str_start_with($object, $v, true)) { $needCompress = false;
} } } else { $minObject = ‘min/’.$object; $needCompress = false; }
return true; } /** * 获取存放资源版本的公文 * 它是置身一个数组里 *
$resState = array( * ‘文件路径’ => ‘对应的本子号’, * ‘文件路径’
=> ‘对应的版本号’, * ‘文件路径’ => ‘对应的版本号’, * ); *
@return [type] [description] */ public function getResState() { if
(file_exists($this->resStatePath)) { require $this->resStatePath;
return $resState; } return []; } /** *
计算文件的本子号,那几个是依照测算文件MD5散列值得到版本号 *
只要文件内容变更了,所总结拿到的散列值就会不同 *
用于判断资源文件是或不是有改变过 * @param [type] $filePath
[description] * @return [type] [description] */ public function
_getResStateVersion($filePath) { return
base_convert(crc32(md5_file($filePath)), 10, 36); } /** *
确保目录可写 * @param [type] $dir [description] * @return [type]
[description] */ private function _ensureWritableDir($dir) { if
(!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); }
else if (!is_writable($dir)) { @chmod($dir, 0777); if
(!is_writable($dir)) { show_error(‘目录’.$dir.’不可写’); } } } /**
* 将滑坡后的资源文件写入到/www/min/下去 * @param [type] $filePath
[description] * @param [type] $minFilePath [description] *
@return [type] [description] */ private function
compressResFileAndSave($filePath, $minFilePath) { if
(!file_put_contents($minFilePath,
$this->compressResFile($filePath))) {
//$CI->exceptions->show_exception(“写入文件{$minFilePath}失败”);
show_error(“写入文件{$minFilePath}失利”, -1); } } /** * 压缩资源文件
* @param [type] $filePath [description] * @return [type]
[description] */ private function compressResFile($filePath) {
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if
($extension === ‘js’) { require_once ‘JShrink/Minifier.php’; return
\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变量是内需减小的资源目录,借使你有新的拍卖目录,可以在此变量里倘若新的目录名即可处理。附上自身测试项指标目录图

必发88 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( * ‘文件路径’ => ‘对应的本子号’, *php多文件上传,文件上传类代码。 ‘文件路径’ =>
‘对应的版本号’, * ‘文件路径’ => ‘对应的版本号’, * ); * @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 [];
    }

(资源版本文件截图:)

必发88 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_php多文件上传,文件上传类代码。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————————————————————-

拍卖完后,看看所生成的公文,那里一个文件会有几个版本,旧版本从未有过去除掉,在付出条件下删不删除都没难题,那里为什么不删除旧版本的压缩文件,那就涉嫌到在创新几个应用服务器代码时所要注意的标题里。在此我就多讲解一点呢,简单地举个例子吗,一般大型项目中的静态资源和模板文件是布署在不一样的机器集群上的,上线的历程中,静态资源和页面文件的配置时间距离或者会尤其长,对于一个特大型互连网选取来说就是在一个很小的年华距离内,都有只怕出现新用户访问,若是旧版本的静态资源删除了,但新本子的静态资源还没计划形成,那么用户就加载不到该静态资源,结果显而易见,所以,一般景色下大家会保留旧版本的静态资源,然后等具备片段布局形成了,再经过一定的本子删除掉也没涉及,其实,那一个不必删除也是足以的,你思考,一个品种发一遍版本,才会调用三回资源文件裁减方法,它只会对修改过的文件进行生成新版本号的静态文件而已。这么些就看个人的做法了。

必发88 5

咱俩得以打开看看,下边那么些就是缩减后的文书的代码了,文件原大小为16K,压缩后大概少了5K,以往是11K,压缩比大概是2/3,假使在大型项目中,一个复杂点的页面会有很大的静态资源文件要加载,通过此办法,大大地狠抓了加载的速度。(恐怕有点朋友认为压缩个几K可能十几K算什么,完全可以忽略,其实自个儿想说的是,当您在大型项目中优化品种的时候,可以裁减几K的代码,也给网站的本性升高了一大截)

必发88 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 收藏
评论

必发88 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_必发88,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地图