您的位置:澳门新葡8455最新网站 > Web前端 > 大型网站优化技术,php多文件上传

大型网站优化技术,php多文件上传

发布时间:2019-10-14 02:14编辑:Web前端浏览(181)

    静态能源文件自动削减并替换到压缩版本(大型网站优化手艺)

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

    原作出处: Kelly   

    那叁次,小编计算和享用一项大型网站优化本领,那正是在品种中活动削减静态财富文件(css、js),并让网站自动加载压缩后的能源文件。当然,那项本事在雅虎35条前端优化建议里也可能有记载,但它那只是给出一个争辨的方案而已,并且应用的是外表压缩工具去减弱,而在自家的档期的顺序中,是直接通过和谐的顺序自动化去收缩全部css、js文件,然后让页面一向加载所降低后的能源,接下去直接进去正题。

    这次试验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的遭逢(英特网搭建无论是搭建LAMP照旧LNMP的科目都五颜六色一无可取,下一次作者会计算和享用怎么着在LINUX下搭建服务器情形的博文,并且搭建的情况必需一遍性搭建产生功的)。所选择的框架是CI框架,所使用的沙盘是Smarty模板引擎。当然了,这么些只是自己所利用的情况而已,即便你是PHP开采者,倘令你要测量检验下本次实验,那么,小编建议你的PHP版本选择5.4上述,至于框架用什么都以足以的。而如果您不是PHP开拓者(你是JSP也许是ASP开辟者或许是其他开垦者),那么您知道好这一思路后,完全能够在温馨熟知的言语里开展实验测量检验。

    一、原理图

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

    率先是财富减弱原理图:

    图片 1

    任何时候是能源文件替换的规律图:

    图片 2

    假诺我们认真通晓何况看懂这两张原理图的话,基本上也就调节了自身所享受的思路。借使依旧不能清楚的话,接下去小编会结合代码,对以上原理图的每一步实行详尽解说。

    二、思路详细分析

    1.率先是调用该滑坡的主意,你能够把该措施放在网址所要加载的公共类的地点,举例每回访问网址都会调用该滑坡方法进行压缩。当然,这几个只是在支付条件才会每趟都调用,假诺是线上的遇到,在你的网址发一遍新本子的时候,调用三次用来生成压缩版的静态能源就能够了。

    class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); //压缩jscss能源文件 $this->compressResHandle(); } /** * 压缩js、css资源文件(优化) * @return [type] [description] */ private function compressResHandle() { $this->load->library('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.随着就调用了 Res迷你fier类里的 compressRes方法。在这里边小编先附上 ResMinifier那一个类的代码,然后方便一步步开展剖判传授

    PHP

    <?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 财富压缩类 */ class ResMinifier { /** 供给减小的财富目录*/ public $compressResDir = ['css', 'js']; /** 忽视压缩的路线,比方此处是js/icon带头的门径忽视压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 能源根目录*/ public $resRootDir; /** 财富版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes() { //获取贮存版本的能源文件 $resState = $this->getResState(); $count = 0; //开首遍历须要减弱的财富目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该财富文件的相对路线$filePath = str_replace('\', '/', $file->getRealPath()); //获取文件相对路线 $object = substr($filePath, strlen($this->resRootDir)); //计算文件的版本号 $state = $this->_getResStateVersion($filePath); //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; } //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p判定是最根本片段之一*****************// //推断文件是或不是存在且早就退换过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFile帕特h)) { continue; } //确认保障/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); } $resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState); } public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) { //获取财富相对路线 $filePath = $this->resRootDir . $object; //判定财富是还是不是留存 if (!file_exists($filePath)) return "财富文件官样文章{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath); //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSION); //是或不是要收缩 $needCompress = true; //推断能源文件是不是是以 .min.css大概.min.js结尾的 //此类结尾平日都以已压缩过,举例jquery.min.js,就不用再压缩了 if (str_end_with($object, '.min.'.$extension, true)) { //压缩后的能源寄放路径,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir)) { //此处是要求减小的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; //看看是不是是忽视的不二法门前缀 foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; } /** * 获取贮存财富版本的公文 * 它是放在二个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; } /** * 计算文件的版本号,这些是借助测算文件MD5散列值获得版本号 * 只要文件内容更改了,所计算获得的散列值就能分化等 * 用于判断财富文件是或不是有改变过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); } /** * 确定保证目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } } /** * 将回降后的财富文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}退步"); show_error("写入文件{$minFilePath}退步", -1); } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不帮忙压缩{extension}文件[$filePath]"); show_error("不帮忙压缩{extension}文件[$filePath]", -1); } } private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); } } 点击打开财富压缩类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    <?php
    defined('BASEPATH') OR exit('No direct script access allowed');
    /**
    * 资源压缩类
    */
    class ResMinifier {
        /** 需要压缩的资源目录*/
        public $compressResDir = ['css', 'js'];
        /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
        public $compressResIngorePrefix = ['js/icon'];
        /** 资源根目录*/
        public $resRootDir;
        /** 资源版本文件路径*/
        private $resStatePath;
     
        public function __construct() {
            $this->resRootDir = WEBROOT . 'www/';
            $this->resStatePath = WEBROOT . 'www/resState.php';
        }
     
        public function compressRes() {
            //获取存放版本的资源文件
            $resState = $this->getResState();
            $count = 0;
     
            //开始遍历需要压缩的资源目录
            foreach ($this->compressResDir as $resDir) {
                foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                    //获取该资源文件的绝对路径
                    $filePath = str_replace('\', '/', $file->getRealPath());
                    //获取文件相对路径
                    $object = substr($filePath, strlen($this->resRootDir));
                    //计算文件的版本号
                    $state = $this->_getResStateVersion($filePath);
     
                    //获取文件的几个参数值
                    if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                        continue;
                    }
     
                    //压缩文件的绝对路径
                    $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
     
                    //************此处p判断是最重要部分之一*****************//
                    //判断文件是否存在且已经改动过
                    if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                        continue;
                    }
     
                    //确保/www/min/目录可写
                    $this->_ensureWritableDir(dirname($minFilePath));
     
                    if ($needCompress) {
                        $this->compressResFileAndSave($filePath, $minFilePath);
                    } else {
                        copy($filePath, $minFilePath);
                    }
     
                    $resState[$object] = $state;
                    $resState[$minObject] = '';
                    $count++;
     
                    if ($count == 50) {
                        $this->_saveResState($resState);
                        $count = 0;
                    }
     
                }
            }
            if($count) $this->_saveResState($resState);
        }
     
        public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
            //获取资源绝对路径
            $filePath = $this->resRootDir . $object;
            //判断资源是否存在
            if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
            //版本号
            $state = $this-> _getResStateVersion($filePath);
            //文件名后缀
            $extension = pathinfo($filePath, PATHINFO_EXTENSION);
            //是否要压缩
            $needCompress = true;
     
            //判断资源文件是否是以 .min.css或者.min.js结尾的
            //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
            if (str_end_with($object, '.min.'.$extension, true)) {
                //压缩后的资源存放路径,放在 /www/min/ 目录下
                $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
                $needCompress = false;
            } else if (in_array($extension, $this->compressResDir)) {
                //此处是需要压缩的文件目录
                $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                //看看是否是忽略的路径前缀
                foreach ($this->compressResIngorePrefix as $v) {
                    if (str_start_with($object, $v, true)) {
                        $needCompress = false;
                    }
                }
            } else {
                $minObject = 'min/'.$object;
                $needCompress = false;
            }
            return true;
        }
     
        /**
         * 获取存放资源版本的文件
         * 它是放在一个数组里
         * $resState = array(
         *         '文件路径' => '对应的版本号',
         *         '文件路径' => '对应的版本号',
         *         '文件路径' => '对应的版本号',
         *     );
         * @return [type] [description]
         */
        public function getResState() {
            if (file_exists($this->resStatePath)) {
                require $this->resStatePath;
                return $resState;
            }
            return [];
        }
     
        /**
         * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
         * 只要文件内容改变了,所计算得到的散列值就会不一样
         * 用于判断资源文件是否有改动过
         * @param  [type] $filePath [description]
         * @return [type]           [description]
         */
        public function _getResStateVersion($filePath) {
            return base_convert(crc32(md5_file($filePath)), 10, 36);
        }
     
        /**
         * 确保目录可写
         * @param  [type] $dir [description]
         * @return [type]      [description]
         */
        private function _ensureWritableDir($dir) {
            if (!file_exists($dir)) {
                @mkdir($dir, 0777, true);
                @chmod($dir, 0777);
            } else if (!is_writable($dir)) {
                @chmod($dir, 0777);
                if (!is_writable($dir)) {
                    show_error('目录'.$dir.'不可写');
                }
            }
        }
     
        /**
         * 将压缩后的资源文件写入到/www/min/下去
         * @param  [type] $filePath    [description]
         * @param  [type] $minFilePath [description]
         * @return [type]              [description]
         */
        private function compressResFileAndSave($filePath, $minFilePath) {
            if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
     
                //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
                show_error("写入文件{$minFilePath}失败", -1);
            }
        }
     
        /**
         * 压缩资源文件
         * @param  [type] $filePath [description]
         * @return [type]           [description]
         */
        private function compressResFile($filePath) {
            $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
            if ($extension === 'js') {
                require_once 'JShrink/Minifier.php';
                return JShrinkMinifier::minify(file_get_contents($filePath));
            } else if ($extension ==='css') {
                $content = file_get_contents($filePath);
                $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
                $content = str_replace(["rn", "r", "n"], '', $content);
                $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
                $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
                $content = str_replace(';}', '}', $content);
                return $content;
            } else {
                //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
                show_error("不支持压缩{extension}文件[$filePath]", -1);
     
            }
        }
     
        private function _saveResState($resState) {
            ksort($resState);
            $content = "<?phpnn$resState = array(n";
            foreach ($resState as $k => $v) {
                $content .= "t '$k' => '$v',n";
            }
            $content .= ");nn";
            file_put_contents($this->resStatePath, $content);
        }
     
    }
     
    点击打开 资源压缩类

    任何类当先二分一代码作者都加了讲明,方便大家快速精晓。这里小编也会对每一行代码进行讲授。

    (1)

    PHP

    /** 要求收缩的财富目录*/ public $compressResDir = ['css', 'js']; /** 忽视压缩的路子,比如此处是js/icon最早的路线忽视压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 财富根目录*/ public $resRootDir; /** 财富版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; }

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

    $compressResDir变量是亟需收缩的财富目录,若是你有新的管理目录,能够在那变量里假诺新的目录名就可以处理。附上本身测量检验项目标目录图

    图片 3

    $compressResIngorePrefix 忽视被减去的不二等秘书籍的不二秘诀前有的是该数组变量的字符串,举例有二个能源路线为 js/icon/bg.js只怕是js/icon_index.js也许是js/icon.header.js,借使在该数组中参与了 js/icon那一个字符串,那么能源路线为js/icon起初的都会被忽视掉,相当于向来跳过,不用压缩。(因为能源文件里总有一对是不须求减小的嘛)

    $resRootDir存放能源根目录的

    $resStatePath 那一个是财富版本文件路线

    (2)走入compressRes() 方法,我们先剖判前面这一段代码

    PHP

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

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

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

    此地首先是调用 $this->getResState() 方法来博取贮存版本的能源文件,此处先跳到该措施看看是什么样写的,其实便是包括该公文,然后重临里面贮存版本号的数组,大家看注释能够明白该公文里置放版本号的格式(顺便附上海教室让大家看看)

    PHP

    /** * 获取存放财富版本的文书 * 它是身处一个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
         * 获取存放资源版本的文件
         * 它是放在一个数组里
         * $resState = array(
         *         '文件路径' => '对应的版本号',
         *         '文件路径' => '对应的版本号',
         *         '文件路径' => '对应的版本号',
         *     );
         * @return [type] [description]
         */
        public function getResState() {
            if (file_exists($this->resStatePath)) {
                require $this->resStatePath;
                return $resState;
            }
            return [];
        }

    (财富版本文件截图:)

    图片 4

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

    接着看compressRes()里的这一段代码

    PHP

    //开首遍历要求降低的资源目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该能源文件的相对路线$filePath = str_replace('\', '/', $file->getRealPath()); //获取文件绝对路线 $object = substr($filePath, strlen($this->resRootDir)); //计算文件的版本号 $state = $this->_getResStateVersion($filePath);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //开始遍历需要压缩的资源目录
            foreach ($this->compressResDir as $resDir) {
                foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                    //获取该资源文件的绝对路径
                    $filePath = str_replace('\', '/', $file->getRealPath());
                    //获取文件相对路径
                    $object = substr($filePath, strlen($this->resRootDir));
                    //计算文件的版本号
                    $state = $this->_getResStateVersion($filePath);

    先是个遍历的是js和css目录 第贰个遍历是将js目录恐怕css目录里的文件都产生路线格局,

    比如说获取文件的相对路线 $filePath 的值是那样子的:

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

    而文件的相对路径$object是这样子的 :

    css/home/index.css

    这里就从头调用$this->_getResStateVersion($filePath)来计量文件的本子号

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

    PHP

    /** * 总计文件的版本号,那些是基于测算文件MD5散列值获得版本号 * 只要文件内容更动了,所总括获得的散列值就能差异 * 用于判定财富文件是还是不是有改观过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); }

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

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

    抑或到版本号后,再看下一段代码,这里开首调用$this->getObjectInfo()方法,这里收获到压缩文件的相对路线$minObject,是还是不是须要压缩$needCompress,版本号$state,文件后缀$extension。

    PHP

    //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; }

    1
    2
    3
    4
    //获取文件的几个参数值
                    if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                        continue;
                    }

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

    PHP

    /** * 获取财富文件有关音讯 * @param [type] $object 能源文件路径(www/css/home/index.css) * @param [type] $minObject 压缩能源文件路线(www/min/css/home/index.ae123a.css) * @param [type] $needCompress 是还是不是须要压缩 * @param [type] $state 文件版本号 * @param [type] $extension 文件名后缀 * @return [type] [description] */ public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) { //获取能源相对路线 $filePath = $this->resRootDir . $object; //推断财富是不是留存 if (!file_exists($filePath)) return "财富文件不设有{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath); //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSION); //是或不是要削减 $needCompress = true; //判定能源文件是不是是以 .min.css大概.min.js结尾的 //此类结尾经常皆以已调减过,举例jquery.min.js,就无须再压缩了 if (str_end_with($object, '.min.'.$extension, true)) { //压缩后的能源存放路径,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir)) { //此处是急需降低的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; //看看是或不是是忽视的门路前缀 foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    /**
         * 获取资源文件相关信息
         * @param  [type] $object       资源文件路径 (www/css/home/index.css)
         * @param  [type] $minObject    压缩资源文件路径 (www/min/css/home/index.ae123a.css)
         * @param  [type] $needCompress 是否需要压缩
         * @param  [type] $state        文件版本号
         * @param  [type] $extension    文件名后缀
         * @return [type]               [description]
         */
        public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
            //获取资源绝对路径
            $filePath = $this->resRootDir . $object;
            //判断资源是否存在
            if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
            //版本号
            $state = $this-> _getResStateVersion($filePath);
            //文件名后缀
            $extension = pathinfo($filePath, PATHINFO_EXTENSION);
            //是否要压缩
            $needCompress = true;
     
            //判断资源文件是否是以 .min.css或者.min.js结尾的
            //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
            if (str_end_with($object, '.min.'.$extension, true)) {
                //压缩后的资源存放路径,放在 /www/min/ 目录下
                $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
                $needCompress = false;
            } else if (in_array($extension, $this->compressResDir)) {
                //此处是需要压缩的文件目录
                $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                //看看是否是忽略的路径前缀
                foreach ($this->compressResIngorePrefix as $v) {
                    if (str_start_with($object, $v, true)) {
                        $needCompress = false;
                    }
                }
            } else {
                $minObject = 'min/'.$object;
                $needCompress = false;
            }
            return true;
        }

    以此办法里的每一行代码基本上都有注释了,所以就不一句句举行疏解了,这里根本看上边包车型客车推断部分:

    if (str_end_with($object, ‘.min.’.$extension, true)) 那一个推断是相比较能源文件路线字串尾部是不是以 .min.$extension 结尾,举例是 jquery.min.js,这种文件本来正是
    压缩过的公文,所以就绝不再实行压缩管理了, $minObject 这些变量寄放的是减掉后的财富文件路线。
    那边附上str_end_with()函数的代码:

    PHP

    /** * 剖断 subject 是不是以 search结尾, 参数钦定是不是忽视大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_end_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len2 > $len1) return false; if ($ignore_case) { return 0 === strcmp(substr($subject, $len1 - $len2), $search); } else { return 0 === strcasecmp(substr($subject, $len1 - $len2), $search); } }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /**
         * 判断 subject 是否以 search结尾, 参数指定是否忽略大小写
         * @param  [type]  $subject     [description]
         * @param  [type]  $search      [description]
         * @param  boolean $ignore_case [description]
         * @return [type]               [description]
         */
        function str_end_with($subject, $search, $ignore_case = false) {
            $len2 = strlen($search);
            if (0 === $len2) return true;
            $len1 = strlen($subject);
            if ($len2 > $len1) return false;
            if ($ignore_case) {
                return 0 === strcmp(substr($subject, $len1 - $len2), $search);
            } else {
                return 0 === strcasecmp(substr($subject, $len1 - $len2), $search);
            }
        }

    if (in_array($extension, $this->compressResDir),这些判别便是是还是不是是需求管理的多少个目录里的。

    然后中间的foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } }

    本条是决断是还是不是是以$this->compressResIngorePrefix属性定义的眼下部分字串开始的路径,是的话就忽略压缩该能源文件。

    剖断到最后else 正是认证该财富文件没有供给裁减了,最终是回去$minObject,$needCompress,$state,$extension这两个变量。

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

    到此地继续回来看 compressRes()方法里面包车型的士代码

    PHP

    //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p判定是最重大片段之一*****************// //决断文件是或不是存在且已经转移过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) { continue; }

    1
    2
    3
    4
    5
    6
    7
    8
    //压缩文件的绝对路径
                    $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
     
                    //************此处p判断是最重要部分之一*****************//
                    //判断文件是否存在且已经改动过
                    if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                        continue;
                    }

    这段代码首先是拼接出压缩文件的相对路线,

    继而下边这些判别是关键的一些,通过这一个论断就足以领略该财富文件是还是不是被改造过,借使改动过的话,就再度对该能源文件实行压缩,假诺没改换过,就持续管理下二个能源文件。看这里的推断:isset($resState[$object]) && $resState[$object] == $state,那一个论断正是判别该公文路径是或不是存在  并且文件中对应的版本号和计算出的版本号是还是不是还同样;isset($resState[$minObject]) &&file_exists($minFilePath),那些是决断压缩文件路线是还是不是留存,况且该压缩文件是不是真实存在目录中。

    看下一段代码,借使能走到这一有的,表达当前的这些财富文件是被改成过的(代码修改过),那么此时就对文本进行削减操作了

    PHP

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

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

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

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

    PHP

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

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

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

    if ($needCompress),那个论断能源文件是不是须求裁减,须要的话调用$this->compressResFileAndSave($filePath, $minFile帕特h);无需的话,直接复制文件到压缩文件路线 copy($filePath, $minFile帕特h);

    先看$this->compressResFileAndSave()

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

    PHP

    /** * 将核减后的财富文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}失利"); show_error("写入文件{$minFilePath}失利", -1); } } /** * 压缩能源文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不帮助压缩{extension}文件[$filePath]"); show_error("不扶持压缩{extension}文件[$filePath]", -1); } }

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

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

    大家先看下这些压缩方法:

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

    贰个用来压缩js文件的PHP类,百度得以找到,调用那几个类的minify()那一个艺术就足以减弱了;而css的削减利用正则替换到裁减,把那多少个空格换行什么的都去掉。到此就减弱成功

    了,然后再将精减后的财富写入到对应的压缩文件路线里去。

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

    进而继续看compressRes()那个主意里的代码,这里开端便是保存新的本子号到$resState数组里 $object=>$state,还应该有就是新的减弱路线$minObject,而这里$count++的效用是,当以此轮回肆拾肆遍就将 $resState这么些数组写入贰遍到 resState.php文件里,这里是由于谨严挂念而已,借使您不加那一个$count的管理那有的也得以,最终写入一回就行了。

    PHP

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

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

    这里看$this->_saveResState($resState),那个方式正是将$resState数组写入到resState.php文件里去的方法。

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

    PHP

    private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    private function _saveResState($resState) {
            ksort($resState);
            $content = "<?phpnn$resState = array(n";
            foreach ($resState as $k => $v) {
                $content .= "t '$k' => '$v',n";
            }
            $content .= ");nn";
            file_put_contents($this->resStatePath, $content);
        }

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

    管理完后,看看所生成的文书,这里三个文件会有三个版本,旧版本并未有去除掉,在付出条件下删不删除都没难题,这里为什么不删除旧版本的压缩文件,这就涉嫌到在立异七个应用服务器代码时所要注意的主题素材里。在这里笔者就多批注一点吧,轻便地举个例证吗,日常大型项目中的静态财富和模板文件是布署在分歧的机械集群上的,上线的进程中,静态财富和页面文件的布署时间隔断或然会那多少个长,对于一个特大型互连网使用来讲就是在三个极小的时日间隔内,都有相当的大或许出现新客商访谈,如若旧版本的静态能源删除了,但新本子的静态能源还没安插产生,那么顾客就加载不到该静态财富,结果同理可得,所以,经常景观下我们会保留旧版本的静态能源,然后等有着片段配置到位了,再通过自然的脚本删除掉也没提到,其实,那个不必删除也是能够的,你思索,一个类别发二遍版本,才会调用贰遍能源文件减弱方法,它只会对修改过的文本进行生成新版本号的静态文件而已。那一个就看个人的做法了。

    图片 5

    大家能够张开看看,上面这几个正是减掉后的文书的代码了,文件原大小为16K,压缩后大约少了5K,今后是11K,压缩比大致是2/3,要是在大型项目中,叁个复杂点的页面会有比非常的大的静态能源文件要加载,通过此办法,大大地增进了加载的快慢。(大概有一些朋友认为压缩个几K也许十几K算什么,完全能够忽视,其实本人想说的是,当您在大型项目中优化品种的时候,可以减少几K的代码,也给网址的属性提升了一大截)

    图片 6

    到此,财富收缩处理就剖判落成了。其实,有早晚基础的爱侣,能够一向看小编享受的极度代码就能够了,如果精通不了,再看自个儿下面这一步步的剖判解说,小编是处在能看过来此博客的对象,无论本领是好只怕是稍弱,都能看懂,所以才对代码一步步地扩充足析传授。(希望各位多多支持四弟)

    ————————————————————————————————————————-

    1. 接下去便是教师怎样替换压缩后的能源文件了。

    这个到Home.php

    PHP

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

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

    上面有加载多个财富文件,我们先看看$this->addResLink();这么些艺术,那几个艺术放在My_Controller.php里:

    PHP

    /** * 能源路线 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
         * 资源路径
         * @param [type] $filePath [description]
         */
        protected function addResLink($filePath) {
            list($filePath, $query) = explode('?', $filePath . '?');
            $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
            foreach ($this->_resLink as $v) {
                if (false === array_search($filePath, $this->_resLink[$extension])) {
                    $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
                }
            }
     
            return $this;
        }

    此处最主要是剖断了财富文件是css依然js,然后将其存放在 $this->_resLink这一个天性里。

    那么这里笔者就先附上My_Controller.php这么些父类的拥有代码吧

    PHP

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

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

    打字与印刷出来 $this->_resLink这一个脾气的布局是那样子的:

    PHP

    Array ( [js] => Array ( [0] => /jquery.all.min.js [1] => index.js ) [css] => Array ( [0] => index.css ) )

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Array
    (
        [js] => Array
            (
                [0] => /jquery.all.min.js
                [1] => index.js
            )
     
        [css] => Array
            (
                [0] => index.css
            )
     
    )

    再回去Home.php里面调用 $this->displayView(‘home/index.tpl’);

    大家看那些措施:

    PHP

    /** * 使用母版页输出二个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null) { //为空则选用暗许母版 if ($masterPage == null) $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v); } //内容部分 $output .= $viewContent; //后面部分增多js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v); } //发送最后输出结果以至服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DIENCORE.'Smarty.class.php'; $this->smarty = new 斯马特y(); $this->smarty->setCompileDir(应用程式PATH . 'cache/'); $this->smarty->setCacheDir(APPPATH . 'cache/'); } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } }

    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模板引擎================================// /* 斯马特y母版页文件路线 */ protected $masterPage = 'default.tpl'; /* 视图像和文字件路线*/ protected $smartyView; /* 要赋值给smarty视图的数额*/ protected $smartyData = []; /* 财富文件*/ protected $_resLink = ['js'=>[], 'css'=>[]]; /** * 使用母版页输出贰个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null) { //为空则选取暗许母版 if ($masterPage == null) $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v); } //内容部分 $output .= $viewContent; //尾巴部分增添js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v); } //发送最后输出结果以致服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DIKoleos.'斯马特y.class.php'; $this->smarty = new Smarty(); $this->smarty->setCompileDir(应用软件PATH . 'cache/'); $this->smarty->setCacheDir(应用软件PATH . 'cache/'); } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } } /** * 能源路线 * @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) { //获取能源相对路线 $file帕特h = $this->resRootDir . $object; //判别能源是还是不是存在 if (!file_exists($filePath)) return "财富文件海市蜃楼{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath); //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSION); //是不是要减弱$needCompress = true; //判定财富文件是或不是是以 .min.css可能.min.js结尾的 //此类结尾通常都以已缩减过,比如jquery.min.js,就不用再压缩了 if (str_end_with($object, '.min.'.$extension, true)) { //压缩后的财富贮存路线,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir)) { //此处是需求减小的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; //看看是或不是是忽略的路径前缀 foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; } /** * 获取寄放能源版本的文书 * 它是放在一个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; } /** * 计算文件的版本号,那么些是依附测算文件MD5散列值获得版本号 * 只要文件内容改动了,所总结获得的散列值就能不等同 * 用于判别能源文件是或不是有改造过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); } /** * 确定保证目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } } /** * 将削减后的能源文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}退步"); show_error("写入文件{$minFilePath}战败", -1); } } /** * 压缩能源文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不扶植压缩{extension}文件[$filePath]"); show_error("不协理压缩{extension}文件[$filePath]", -1); } } private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); } } 点击展开

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    <?php
    defined('BASEPATH') OR exit('No direct script access allowed');
    /**
    * 资源压缩类
    */
    class ResMinifier {
        /** 需要压缩的资源目录*/
        public $compressResDir = ['css', 'js'];
        /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
        public $compressResIngorePrefix = ['js/icon'];
        /** 资源根目录*/
        public $resRootDir;
        /** 资源版本文件路径*/
        private $resStatePath;
     
        public function __construct() {
            $this->resRootDir = WEBROOT . 'www/';
            $this->resStatePath = WEBROOT . 'www/resState.php';
        }
     
        public function compressRes() {
            //获取存放版本的资源文件
            $resState = $this->getResState();
            $count = 0;
     
            //开始遍历需要压缩的资源目录
            foreach ($this->compressResDir as $resDir) {
                foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                    //获取该资源文件的绝对路径
                    $filePath = str_replace('\', '/', $file->getRealPath());
     
                    //获取文件相对路径
                    $object = substr($filePath, strlen($this->resRootDir));
     
                    //计算文件的版本号
                    $state = $this->_getResStateVersion($filePath);
     
                    //获取文件的几个参数值
                    if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                        continue;
                    }
     
                    //压缩文件的绝对路径
                    $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
     
                    //************此处p判断是最重要部分之一*****************//
                    //判断文件是否存在且已经改动过
                    if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                        continue;
                    }
     
                    //确保/www/min/目录可写
                    $this->_ensureWritableDir(dirname($minFilePath));
     
                    if ($needCompress) {
                        $this->compressResFileAndSave($filePath, $minFilePath);
                    } else {
                        copy($filePath, $minFilePath);
                    }
     
                    $resState[$object] = $state;
                    $resState[$minObject] = '';
                    $count++;
     
                    if ($count == 50) {
                        $this->_saveResState($resState);
                        $count = 0;
                    }
     
                }
            }
            if($count) $this->_saveResState($resState);
        }
     
        /**
         * 获取资源文件相关信息
         * @param  [type] $object       资源文件路径 (www/css/home/index.css)
         * @param  [type] $minObject    压缩资源文件路径 (www/min/css/home/index.ae123a.css)
         * @param  [type] $needCompress 是否需要压缩
         * @param  [type] $state        文件版本号
         * @param  [type] $extension    文件名后缀
         * @return [type]               [description]
         */
        public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
            //获取资源绝对路径
            $filePath = $this->resRootDir . $object;
            //判断资源是否存在
            if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
            //版本号
            $state = $this-> _getResStateVersion($filePath);
            //文件名后缀
            $extension = pathinfo($filePath, PATHINFO_EXTENSION);
            //是否要压缩
            $needCompress = true;
     
            //判断资源文件是否是以 .min.css或者.min.js结尾的
            //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
            if (str_end_with($object, '.min.'.$extension, true)) {
                //压缩后的资源存放路径,放在 /www/min/ 目录下
                $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
                $needCompress = false;
            } else if (in_array($extension, $this->compressResDir)) {
                //此处是需要压缩的文件目录
                $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                //看看是否是忽略的路径前缀
                foreach ($this->compressResIngorePrefix as $v) {
                    if (str_start_with($object, $v, true)) {
                        $needCompress = false;
                    }
                }
            } else {
                $minObject = 'min/'.$object;
                $needCompress = false;
            }
            return true;
        }
     
        /**
         * 获取存放资源版本的文件
         * 它是放在一个数组里
         * $resState = array(
         *         '文件路径' => '对应的版本号',
         *         '文件路径' => '对应的版本号',
         *         '文件路径' => '对应的版本号',
         *     );
         * @return [type] [description]
         */
        public function getResState() {
            if (file_exists($this->resStatePath)) {
                require $this->resStatePath;
                return $resState;
            }
            return [];
        }
     
        /**
         * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
         * 只要文件内容改变了,所计算得到的散列值就会不一样
         * 用于判断资源文件是否有改动过
         * @param  [type] $filePath [description]
         * @return [type]           [description]
         */
        public function _getResStateVersion($filePath) {
            return base_convert(crc32(md5_file($filePath)), 10, 36);
        }
     
        /**
         * 确保目录可写
         * @param  [type] $dir [description]
         * @return [type]      [description]
         */
        private function _ensureWritableDir($dir) {
            if (!file_exists($dir)) {
                @mkdir($dir, 0777, true);
                @chmod($dir, 0777);
            } else if (!is_writable($dir)) {
                @chmod($dir, 0777);
                if (!is_writable($dir)) {
                    show_error('目录'.$dir.'不可写');
                }
            }
        }
     
        /**
         * 将压缩后的资源文件写入到/www/min/下去
         * @param  [type] $filePath    [description]
         * @param  [type] $minFilePath [description]
         * @return [type]              [description]
         */
        private function compressResFileAndSave($filePath, $minFilePath) {
            if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
     
                //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
                show_error("写入文件{$minFilePath}失败", -1);
            }
        }
     
        /**
         * 压缩资源文件
         * @param  [type] $filePath [description]
         * @return [type]           [description]
         */
        private function compressResFile($filePath) {
            $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
            if ($extension === 'js') {
                require_once 'JShrink/Minifier.php';
                return JShrinkMinifier::minify(file_get_contents($filePath));
            } else if ($extension ==='css') {
                $content = file_get_contents($filePath);
                $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
                $content = str_replace(["rn", "r", "n"], '', $content);
                $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
                $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
                $content = str_replace(';}', '}', $content);
                return $content;
            } else {
                //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
                show_error("不支持压缩{extension}文件[$filePath]", -1);
     
            }
        }
     
        private function _saveResState($resState) {
            ksort($resState);
            $content = "<?phpnn$resState = array(n";
            foreach ($resState as $k => $v) {
                $content .= "t '$k' => '$v',n";
            }
            $content .= ");nn";
            file_put_contents($this->resStatePath, $content);
        }
     
    }
     
    点击打开

    Common.php

    PHP

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

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

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

    XHTML

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

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

     

    别的附上JShrink那一个PHP类的链接给我们下载 

    假设我们要么感到缺乏OK的话,作者间接将那些试验项目打包供大家下载下来学习和领悟:

    四、结语

    最终本人来享受我们线上项指标切切实实贯彻方案:

    大家的品种分线上遭逢、开拓条件和测量检验景况,在付出和测验情形中,大家每一回访谈都会调用压缩文件的接口,然后再对转移的能源文件的大大小小是要做判别的,倘使缩减后文件过小,将在求将该财富文件的代码合併到其余国资本源文件里去,以此收缩不供给的HTTP乞请(因为文件太小,财富的下载时间远远低于HTTP诉求响应所开销的时刻);另一个是图表的管理,全体图片都要透过压缩技能透过(比如在:  这几个网址去减弱图片),在PC端,固然是小Logo的话,使用图片合併的方式张开优化,详细情况可参看本身的这篇博文:http://www.cnblogs.com/it-cen/p/4618954.html    而在wap端的图纸管理利用的是base64编码格局来拍卖图片,详细情形能够参谋自个儿的那篇博文:  ,当页面输出时,会使用redis来缓存页面(为何用内部存款和储蓄器来缓存实际不是利用页面缓存,那一个今后再享受给我们)。借使是线上蒙受,每发一回版本,才会调用一下能源文件减少这么些接口,并且线上的静态财富(css、js、图片)是存放在Ali云的OSS里的,与我们的应用服务器是分手的。那是我们线上体系的一有的优消除决方案,当然了,还会有愈来愈多优化本领,作者会在今后各样总计和分享出来,方便大家一块学习和调换。

    此番博文就享受到此,多谢观望此博文的恋人们。

    1 赞 1 收藏 评论

    图片 7

    文本上传例子

     代码如下

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

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

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

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

    ?>

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

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

    文件上传类代码

     代码如下

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

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

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

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

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

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

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

    return count($this->save_info);
    }

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

    return TRUE;
    }

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

    return FALSE;
    }

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

    return $p['extension'];
    }

    /*
     *收获文件名(不富含扩张名)
     *
     *@param string $filename
     *@param string $type
     *@access private
     *@return boolean
     */
    function getBaseName($filename,$ext_name)
    {
    $basename = basename($filename,$ext_name);

    return $basename;
    }

    /*
     *
     *
     *
     */
    function showErrorInfo()
    {
    if(count($this->error_info) != 0){
    //echo 'error...<br/>';
    foreach($this->error_info as $k=>$v){
    echo ($k+1),':',$v,'<br/>';
    }
    }
    }

    function getSaveInfo()
    {
    return $this->save_info;
    }
    }

    //$upload = new UploadFile('','');
    //$upload = new UploadFile();
    //$upload->showErrorInfo();

    ?>

    本文由澳门新葡8455最新网站发布于Web前端,转载请注明出处:大型网站优化技术,php多文件上传

    关键词: