#18885392 Optimizer Template 에 Cache적용

git-svn-id: http://xe-core.googlecode.com/svn/sandbox@7451 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
ngleader 2010-05-12 08:37:39 +00:00
parent f07cc09e4f
commit 96b197c3a5
4 changed files with 232 additions and 152 deletions

View file

@ -60,6 +60,14 @@
if(!count($targets)) return $this->_getOptimizedRemoved($files); if(!count($targets)) return $this->_getOptimizedRemoved($files);
$list_file_hash = md5($hash); $list_file_hash = md5($hash);
$oCacheHandler = &CacheHandler::getInstance('template');
if($oCacheHandler->isSupport()){
if(!$oCacheHandler->isValid($list_file_hash)){
$buff = array();
foreach($targets as $file) $buff[] = $file['file'];
$oCacheHandler->put($list_file_hash, $buff);
}
}else{
$list_file = FileHandler::getRealPath($this->cache_path . $list_file_hash); $list_file = FileHandler::getRealPath($this->cache_path . $list_file_hash);
if(!file_exists($list_file)){ if(!file_exists($list_file)){
@ -69,6 +77,7 @@
FileHandler::writeFile($list_file, $str); FileHandler::writeFile($list_file, $str);
} }
}
array_unshift($files, array('file' => sprintf($this->script_file, $list_file_hash, $type) , 'media' => 'all')); array_unshift($files, array('file' => sprintf($this->script_file, $list_file_hash, $type) , 'media' => 'all'));
$files = $this->_getOptimizedRemoved($files); $files = $this->_getOptimizedRemoved($files);

View file

@ -55,6 +55,16 @@
$this->tpl_path = preg_replace('/^\.\//','',$tpl_path); $this->tpl_path = preg_replace('/^\.\//','',$tpl_path);
$this->tpl_file = $tpl_file; $this->tpl_file = $tpl_file;
$oCacheHandler = &CacheHandler::getInstance('template');
if($oCacheHandler->isSupport()){
$buff = $oCacheHandler->get('template:'.$tpl_file, filemtime(FileHandler::getRealPath($tpl_file)));
if(!$buff){
$buff = $this->_compileTplFile($tpl_file);
$oCacheHandler->put('template:'.$tpl_file, $buff);
}
$output = $this->_fetch('', $buff, $tpl_path);
}else{
// get cached compiled file name // get cached compiled file name
$compiled_tpl_file = FileHandler::getRealPath($this->_getCompiledFileName($tpl_file)); $compiled_tpl_file = FileHandler::getRealPath($this->_getCompiledFileName($tpl_file));
@ -63,6 +73,7 @@
// make a result, combining Context and compiled_tpl_file // make a result, combining Context and compiled_tpl_file
$output = $this->_fetch($compiled_tpl_file, $buff, $tpl_path); $output = $this->_fetch($compiled_tpl_file, $buff, $tpl_path);
}
if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start; if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start;

View file

@ -4,17 +4,20 @@
* @brief css js Optimizer 처리 gateway * @brief css js Optimizer 처리 gateway
* *
**/ **/
if(!$_GET['t'] || !$_GET['l']) exit; if(!$_GET['t'] || !$_GET['l']) exit;
// set env // set env
$XE_PATH = substr(dirname(__FILE__),0,strlen('common')*-1); $XE_PATH = substr(dirname(__FILE__),0,strlen('common')*-1);
define('__XE_PATH__', $XE_PATH); define('_XE_PATH_', $XE_PATH);
define('__ZBXE__', true); define('__ZBXE__', true);
define('__XE_LOADED_CLASS__', true); define('__XE_LOADED_CLASS__', true);
include _XE_PATH_ . 'config/config.inc.php';
include _XE_PATH_ . 'files/config/db.config.php';
include _XE_PATH_ . 'classes/handler/Handler.class.php';
include _XE_PATH_ . 'classes/cache/CacheHandler.class.php';
include $XE_PATH . 'config/config.inc.php'; $oCacheHandler = new CacheHandler('template', $db_info);
$cache_support = $oCacheHandler->isSupport();
$XE_WEB_PATH = substr($XE_PATH,strlen($_SERVER['DOCUMENT_ROOT'])); $XE_WEB_PATH = substr($XE_PATH,strlen($_SERVER['DOCUMENT_ROOT']));
if(substr($XE_WEB_PATH,-1) != "/") $XE_WEB_PATH .= "/"; if(substr($XE_WEB_PATH,-1) != "/") $XE_WEB_PATH .= "/";
@ -22,14 +25,9 @@ $cache_path = $XE_PATH . 'files/cache/optimized/';
$type = $_GET['t']; $type = $_GET['t'];
$list_file = $cache_path . $_GET['l']; $list_file = $cache_path . $_GET['l'];
// check
if(!file_exists($list_file)) exit;
$list = include($list_file);
if(!is_array($list)) exit;
function getRealPath($file){ function getRealPath($file){
global $XE_PATH; if($file{0}=='.' && $file{1} =='/') $file = _XE_PATH_.substr($file, 2);
if($file{0}=='.' && $file{1} =='/') $file = $XE_PATH.substr($file, 2);
return $file; return $file;
} }
@ -44,14 +42,24 @@ function getMaxMtime($list){
return max($mtime); return max($mtime);
} }
// max mtime // check
$mtime = getMaxMtime(array_merge($list,array($list_file))); if($cache_support){
$list = $oCacheHandler->get($_GET['l']);
$mtime = getMaxMtime($list);
}else{
if(!file_exists($list_file)) exit;
$list = include($list_file);
$mtime = getMaxMtime(array_merge($list,array($list_file)));
}
if(!is_array($list)) exit;
// set content-type
if($type == '.css'){ if($type == '.css'){
$content_type = 'text/css'; $content_type = 'text/css';
} else if($type == '.js') { } else if($type == '.js') {
$content_type = 'text/javascript'; $content_type = 'text/javascript';
} }
header("Content-Type: ".$content_type."; charset=UTF-8"); header("Content-Type: ".$content_type."; charset=UTF-8");
// return 304 // return 304
@ -64,14 +72,28 @@ if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
} }
} }
header("Cache-Control: private, max-age=2592000"); function useContentEncoding(){
header("Pragma: cache"); if( (defined('__OB_GZHANDLER_ENABLE__') && __OB_GZHANDLER_ENABLE__ == 1)
header("Connection: close"); && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')!==false
header("Last-Modified: " . substr(gmdate('r', $mtime), 0, -5). "GMT"); && function_exists('ob_gzhandler')
header("ETag: \"". md5(join(' ', $list)) .'-'. dechex($mtime)."\""); && extension_loaded('zlib')) {
return true;
}
return false;
}
function printFileList($list){ function printFileList($list){
$output = ''; global $mtime, $cache_support, $oCacheHandler;
$content_encoding = useContentEncoding();
$output = null;
if($cache_support){
$cache_key = md5('optimized:'. join('',$list) . ($content_encoding?'gzip':'') );
$output = $oCacheHandler->get($cache_key, $mtime);
}
if(!$output){
for($i=0,$c=count($list);$i<$c;$i++){ for($i=0,$c=count($list);$i<$c;$i++){
$file = getRealPath($list[$i]); $file = getRealPath($list[$i]);
if(file_exists($file)){ if(file_exists($file)){
@ -80,20 +102,89 @@ function printFileList($list){
} }
} }
if( (defined('__OB_GZHANDLER_ENABLE__') && __OB_GZHANDLER_ENABLE__ == 1) if($content_encoding) $output = ob_gzhandler($output, 5);
&& strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')!==false
&& function_exists('ob_gzhandler')
&& extension_loaded('zlib')) {
header("Content-Encoding: gzip");
$output = ob_gzhandler($output, 5);
} }
if($cache_support) $oCacheHandler->put($cache_key, $output);
if($content_encoding){
header("Content-Encoding: gzip");
}
header("Content-Length: ". strlen($output)); header("Content-Length: ". strlen($output));
echo $output; echo $output;
} }
if($type == '.css'){ function write($file_name, $buff, $mode='w'){
function convertEncodingStr($str) { $file_name = getRealPath($file_name);
if(@!$fp = fopen($file_name,$mode)) return false;
fwrite($fp, $buff);
fclose($fp);
@chmod($file_name, 0644);
}
function read($file_name) {
$file_name = getRealPath($file_name);
if(!file_exists($file_name)) return;
$filesize = filesize($file_name);
if($filesize<1) return;
if(function_exists('file_get_contents')) return file_get_contents($file_name);
$fp = fopen($file_name, "r");
$buff = '';
if($fp) {
while(!feof($fp) && strlen($buff)<=$filesize) {
$str = fgets($fp, 1024);
$buff .= $str;
}
fclose($fp);
}
return $buff;
}
function makeCacheFileCSS($css_file, $cache_file, $return=false){
$str = read($css_file);
$str = replaceCssPath($css_file, trim(convertEncodingStr($str)));
if($return){
return $str;
}else{
write($cache_file, $str."\n");
unset($str);
}
}
function replaceCssPath($file, $str) {
global $tmp_css_path;
// css 파일의 위치를 구함
$tmp_css_path = preg_replace("/^\.\//is","",dirname($file))."/";
// url() 로 되어 있는 css 파일의 경로를 변경
$str = preg_replace_callback('/url\(([^\)]*)\)/is', '_replaceCssPath', $str);
// charset 지정 문구를 제거
$str = preg_replace('!@charset([^;]*?);!is','',$str);
return $str;
}
function _replaceCssPath($matches) {
global $tmp_css_path, $XE_WEB_PATH;
$path = str_replace(array('"',"'"),'',$matches[1]);
if(substr($path,0,1)=='/' || strpos($path,'://')!==false || strpos($path,'.htc')!==false) return 'url('.$path.')';
if(substr($path,0,2)=='./') $path = substr($path,2);
$target = $XE_WEB_PATH.$tmp_css_path.$path;
while(strpos($target,'/../')!==false) {
$target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target);
}
return 'url('.$target.')';
}
function convertEncodingStr($str) {
$charset_list = array( $charset_list = array(
'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932', 'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932',
'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS', 'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS',
@ -115,72 +206,40 @@ if($type == '.css'){
} }
return $str; return $str;
}
// 200
header("Cache-Control: private, max-age=2592000");
header("Pragma: cache");
header("Connection: close");
header("Last-Modified: " . substr(gmdate('r', $mtime), 0, -5). "GMT");
header("ETag: \"". md5(join(' ', $list)) .'-'. dechex($mtime)."\"");
if($type == '.js'){
printFileList($list);
}else if($type == '.css'){
if($cache_support){
foreach($list as $file){
$cache_file = $cache_path . md5($file);
$css[] = getRealPath($cache_file);
} }
function write($file_name, $buff, $mode='w'){ $cache_key = md5('optimized:'. join('',$css) . ($content_encoding?'gzip':'') );
$file_name = getRealPath($file_name); $buff = $oCacheHandler->get($cache_key, $mtime);
if(@!$fp = fopen($file_name,$mode)) return false; if(!$buff){
fwrite($fp, $buff);
fclose($fp);
@chmod($file_name, 0644);
}
function read($file_name) {
$file_name = getRealPath($file_name);
if(!file_exists($file_name)) return;
$filesize = filesize($file_name);
if($filesize<1) return;
if(function_exists('file_get_contents')) return file_get_contents($file_name);
$fp = fopen($file_name, "r");
$buff = ''; $buff = '';
if($fp) { foreach($list as $file){
while(!feof($fp) && strlen($buff)<=$filesize) { $cache_file = $cache_path . md5($file);
$str = fgets($fp, 1024); $buff .= makeCacheFileCSS($file, getRealPath($cache_file), true);
$buff .= $str; $css[] = getRealPath($cache_file);
}
fclose($fp);
}
return $buff;
} }
function makeCacheFileCSS($css_file, $cache_file){ $oCacheHandler->put($cache_key, $buff);
$str = read($css_file);
$str = replaceCssPath($css_file, trim(convertEncodingStr($str)));
write($cache_file, $str."\n");
unset($str);
}
function replaceCssPath($file, $str) {
global $tmp_css_path;
// css 파일의 위치를 구함
$tmp_css_path = preg_replace("/^\.\//is","",dirname($file))."/";
// url() 로 되어 있는 css 파일의 경로를 변경
$str = preg_replace_callback('/url\(([^\)]*)\)/is', '_replaceCssPath', $str);
// charset 지정 문구를 제거
$str = preg_replace('!@charset([^;]*?);!is','',$str);
return $str;
}
function _replaceCssPath($matches) {
global $tmp_css_path, $XE_WEB_PATH;
$path = str_replace(array('"',"'"),'',$matches[1]);
if(substr($path,0,1)=='/' || strpos($path,'://')!==false || strpos($path,'.htc')!==false) return 'url('.$path.')';
if(substr($path,0,2)=='./') $path = substr($path,2);
$target = $XE_WEB_PATH.$tmp_css_path.$path;
while(strpos($target,'/../')!==false) {
$target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target);
}
return 'url('.$target.')';
} }
printFileList($css);
}else{
foreach($list as $file){ foreach($list as $file){
$cache_file = $cache_path . md5($file); $cache_file = $cache_path . md5($file);
$cache_mtime = getMtime($cache_file); $cache_mtime = getMtime($cache_file);
@ -194,7 +253,7 @@ if($type == '.css'){
} }
printFileList($css); printFileList($css);
}else{ }
printFileList($list);
} }
?> ?>

View file

@ -133,6 +133,7 @@
require(_XE_PATH_.'classes/handler/Handler.class.php'); require(_XE_PATH_.'classes/handler/Handler.class.php');
require(_XE_PATH_.'classes/xml/XmlParser.class.php'); require(_XE_PATH_.'classes/xml/XmlParser.class.php');
require(_XE_PATH_.'classes/xml/XmlJsFilter.class.php'); require(_XE_PATH_.'classes/xml/XmlJsFilter.class.php');
require(_XE_PATH_.'classes/cache/CacheHandler.class.php');
require(_XE_PATH_.'classes/context/Context.class.php'); require(_XE_PATH_.'classes/context/Context.class.php');
require(_XE_PATH_.'classes/db/DB.class.php'); require(_XE_PATH_.'classes/db/DB.class.php');
require(_XE_PATH_.'classes/file/FileHandler.class.php'); require(_XE_PATH_.'classes/file/FileHandler.class.php');