本文旨在解決php模板中模塊化視圖加載css樣式文件和js樣式的問題。
分模塊化的php模板中,控制器輸出的視圖旨在body標籤中,而不去關心頭部和尾部樣式。
這樣在模塊化視圖中加載其所需的樣式和js文件位置就成了一個問題。
這個問題可以通過在佈局的樣式模板中添加js和css替代變量解決,視圖中通過統一的方法去加載所需文件。
如果我們想優化頁面的加載速度,可以根據壓縮css和js文件提高頁面的訪問速度。同時合併文件又能再提高訪問速度。
於是乎,我採用了這用方法來優化腳本文件和訪問速度。
1.通過統一的方法將所需加載的文件路徑保存
2.在視圖將要輸出時,合併壓縮文件,使用替代文件輸出引用。
/*
*添加js文件
* @param $files array js文件地址數組
*/
function add_js_to_view($files)
{
static $default_head_js = array();//定義靜態變量存儲添加的js文件
$default_head_js = array_merge($default_head_js,$files);//合併已添加的文件
$ci->view_data['default_head_js'] = $default_head_js;//將此靜態變量輸出到模板中使用(此行爲僞代碼)
return;
}
/*
* 壓縮js文件(同理可處理css文件)
* 此處理過程爲:檢測配置文件中是否有過這些文件合併的壓縮文件,同時檢測資源的改變,
*
* 模板中使用 echo compress_js($default_head_js) 輸出壓縮的文件
* @param $arr array 需要壓縮的文件地址數組
*/
function compress_js($arr){
if(!$arr && !is_array($arr)) return ;
$base_url = dirname(BASEPATH).'/static/compress/';//壓縮文件存放目錄
/*實例化壓縮類*/
$yui = new yuicompressor(array(
'java_home'=>'java', //或自己指定 jdk 安裝的 bin 目錄 (絕對路徑)
'jar_file'=>$base_url.'yuicompressor-2.4.8.jar',
'save_path'=>$base_url, //必須有可寫權限
// -------- 全局設置 --------- //
'charset'=>'utf-8', //文件的編碼
'line-break'=>false, //在指定的列後插入一個 line-bread 符號
// -------- javascript 代碼的配置選項 --------- //
'nomunge'=>false, //只是簡單壓縮,清除空行空格註釋等。
'semi'=>false, //保留所有的分號
'optimizations'=>false, //禁止優化代碼.
));
$out_name = '';//最終js文件名
$tag_new = true;//是否需要重新合併壓縮
if(file_exists($base_url.'config.php')){//檢測配置文件是否存在
$content = file_get_contents($base_url.'config.php');
if($content != ''){//檢測配置文件裏的內容是否爲空
$compress_config = json_decode($content,true);
$config_key = '';//此合併文件的key
foreach ($arr as $a){
$config_key .= $a.'_';//拼接key值
}
if(isset($compress_config[$config_key])){//判斷此
$tag = false;//記錄資源是否有變動
foreach ($arr as $a){
@$filemtime = filemtime($a);//獲取文件上傳修改時間戳
if($compress_config[$config_key][$a]['time'] != $filemtime){
@unlink($compress_config[$config_key]['compress_name'].'.min.js');//刪除無用的文件
unset($compress_config[$config_key]);
$tag = true;//資源有變動,即資源上次更改時間戳有變化
break;
}
}
if($tag && file_exists('/static/compress/'.$compress_config[$config_key]['compress_name'].'.min.js')) {//如果資源無變動,並且文件存在,則使用次文件
$out_name = $compress_config[$config_key]['compress_name'];
$tag_new = false;
}
}
}
}
if($tag_new){
$config_key = '';
$compress_name = 'index_'.time();//編譯文件名
$compress_config[$config_key] = array();
foreach ($arr as $a){
$config_key .= $a.'_';
file_put_contents($base_url.$compress_name.'.js',file_get_contents($a).";",FILE_APPEND);//合併所以文件
}
foreach ($arr as $a){
@$compress_config[$config_key][$a]['time'] = filemtime($a);
}
$compress_config[$config_key]['compress_name'] = 'index_'.time();
file_put_contents($base_url.'config.php',json_encode($compress_config));
//對單個文件壓縮
$resutlt = $yui->compress($base_url.$compress_name.'.js');
$out_name = $compress_config[$config_key]['compress_name'];
}
echo "<script src='" . base_url('/static/compress/'.$out_name.'.min.js') . "'></script>\r\n";//輸出壓縮後的js文件引用標籤
}
///*
// * 參考此類
//
//
// * PHP YUICompressor Class (Dual licensed under the MIT)
// * 風吟 (http://fengyin.name/guestbook.php)
// * DEMO http://sweet.fengyin.name/ (yui online compressor)
// ----------------------------------------------------------
// 要求: dk 1.4+ php exec()
// 作用: 使用 yuicompressor 批量壓縮一個目錄的 js 或者 css 文件.也可以對單個文件進行壓縮
// ----------------------------------------------------------
//
// //Windows 調用方式:
//
//
//$yui = new yuicompressor(array(
// 'java_home'=>'java', //或自己指定 jdk 安裝的 bin 目錄 (絕對路徑)
// 'jar_file'=>'D:\www\htdocs\yuicompressor.jar',
// 'save_path'=>'D:\www\htdocs\results\\', //必須有可寫權限
// // -------- 全局設置 --------- //
// 'charset'=>'utf-8', //文件的編碼
// 'line-break'=>false, //在指定的列後插入一個 line-bread 符號
// // -------- javascript 代碼的配置選項 --------- //
// 'nomunge'=>false, //只是簡單壓縮,清除空行空格註釋等。
// 'semi'=>false, //保留所有的分號
// 'optimizations'=>false, //禁止優化代碼.
// ));
//
// //對單個文件壓縮
// $resutlt = $yui->compress('D:\www\htdocs\swfobject_src.js');
// print_r ($resutlt);
//
// //對目錄文件壓縮
// $resutlt = $yui->directory('D:\www\htdocs\\');
// print_r($resutlt);
//
// ----------------------------------------------------------
//
// //Linux 調用方式:
//
// $yui = new yuicompressor(array(
// 'java_home'=>'java', //或自己指定 jdk 安裝的 bin 目錄 (絕對路徑)
// 'jar_file'=>'/home/admin/yuicompressor-2.4.2.jar',
// 'save_path'=>'/home/admin/results/', //必須有可寫權限
// // -------- 全局設置 --------- //
// 'charset'=>'utf-8', //文件的編碼
// 'line-break'=>false, //在指定的列後插入一個 line-bread 符號
// // -------- javascript 代碼的配置選項 --------- //
// 'nomunge'=>false, //只是簡單壓縮,清除空行空格註釋等。
// 'semi'=>false, //保留所有的分號
// 'optimizations'=>false, //禁止優化代碼.
// ));
//
// //對單個文件壓縮
// $resutlt = $yui->compress('/home/admin/style.css');
// print_r ($resutlt);
//
// //對目錄文件壓縮
// $resutlt = $yui->directory('/home/admin/');
// print_r($resutlt);
//
// */
class yuicompressor {
function __construct($options = array()) {
$this->options = $options;
}
function args($o) {
$jsargs = '';
$line_break = '';
$charset = '';
$o['line-break'] && ($line_break = ' --line-break ' . $o['line-break'] . ' ');
$o['charset'] && ($charset = ' --charset ' . $o['charset'] . ' ');
$o['nomunge'] && ($jsargs .= ' --nomunge ');
$o['semi'] && ($jsargs .= ' --preserve-semi ');
$o['optimizations'] && ($jsargs .= ' --disable-optimizations ');
$exten = $this->getExtension($o['file']);
$cmd = array();
$newfile = $o['save_path'] . $this->replace($o['file']);
$cmd['file'] = $newfile;
$cmd['shell'] = $o['java_home'] . ' -jar ' . $o['jar_file'] . ' --type ' . $exten['extension'] . $charset . $line_break . $jsargs . $o['file']. ' > ' . $newfile;
return $cmd;
}
function getExtension($fn) {
return pathinfo(strtolower($fn));
}
function replace($fn) {
$exten = $this->getExtension($fn);
return str_replace('.'.$exten['extension'], '.min.' . $exten['extension'], $exten['basename']);
}
function exec($cmd) {
exec($cmd['shell'].' 2>&1',$out, $status);
return array(
'shell' => $cmd['shell'],
'out' => implode("\n",$out),
'status' => $status,
'success' => $cmd['file']
);
}
function ls($dir) {
!($dh = opendir($dir)) && exit('open directory error');
while (($file = readdir($dh)) !== false) {
$exten = $this->getExtension($file);
if ($exten['extension'] == 'js' || $exten['extension'] == 'css') {
$files[] = $dir . $file;
}
}
closedir($dh);
return $files;
}
function directory($dir) {
!is_dir($dir) && exit('directory error');
foreach ($this->ls($dir) as $file) {
$fn[] = $this->compress($file);
}
return $fn;
}
function compress($file) {
$this->options['file'] = $file;
return $this->exec($this->args($this->options));
}
}