2013-02-13 54 views
2

我正在使用此代码将css文件缓存到中间自己的CMS中。ob_start缓存CSS

<?php 
ob_start("ob_gzhandler"); 
ob_start("compress"); 
header("Content-type: text/css; charset: UTF-8"); 
header("Cache-Control: must-revalidate"); 
$off = 3600; 
$exp = "Expires: " . gmdate("D, d M Y H:i:s", time() + $off) . " GMT"; 
header($exp); 

function compress($buffer) { 
    $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer); // remove comments 
    $buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer); // remove tabs, spaces, newlines, etc. 
    return $buffer; 
} 

require_once('style1.css'); 
require_once('style2.css'); 

?> 

这段代码的一个很大的局限是我无法将参数传递给我的“压缩”函数。 例如,如果我有一个css文件到另一个目录中,图像的相对路径不会被替换。

当我打电话给我的压缩函数并使用例如类似的东西时,您是否知道添加参数的方法?

$buffer = str_replace('url("', 'url("'.$directory, $buffer); 

任何建议都非常感谢!


编辑 - >最终的解决方案

@Jack建议后,我来到这个源。

用法:在HTML页面的标题中加入这一行: <link href="cacheCSS.php" rel="stylesheet" type="text/css" />

ob_start("ob_gzhandler"); 

class CWD { 
    private $path; 

    public function __construct($path=NULL){ 
     if(!isset($path)) $path = ''; 
     $this->setPath($path); 
    } 

    public function setPath($path){ 
     $this->path = $path; 
    } 

    public function getPath() { 
     return $this->path; 
    } 
} 

$directory = new CWD(); 
$compress = function($buffer) use ($directory) { 
    $buffer = str_replace('url("', 'url("'.$directory->getPath(), $buffer); 
    $buffer = str_replace('url(\'', 'url(\''.$directory->getPath(), $buffer); 
    $buffer = preg_replace('#^\s*//.+$#m', "", $buffer); 
    $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer); 
    $buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer); 
    return $buffer; 
}; 

ob_start($compress); 

header("Content-type: text/css; charset: UTF-8"); 
header("Cache-Control: must-revalidate"); 
$off = 0; # Set to a reaonable value later, say 3600 (1 hr); 
$exp = "Expires: " . gmdate("D, d M Y H:i:s", time() + $off) . " GMT"; 
header($exp); 

/* List of CSS files*/ 
$directory->setPath('path1/'); 
include('path1/style1.css'); 

ob_flush(); 
$directory->setPath('path2/'); 
include('path2/style2.css'); 

ob_flush(); 
$directory->setPath('path3/'); 
include('path3/style3.css'); 

回答

3

由于PHP 5.3,你可以使用闭包来实现:

$directory = 'whatever'; 

$compress = function($buffer) use ($directory) { 
    $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer); // remove comments 
    $buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer); // remove tabs, spaces, newlines, etc. 

    $buffer = str_replace('url("', 'url("'.$directory, $buffer); 

    return $buffer; 
} 

ob_start($compress); 

更新

如果您的目录可以更改,您可能需要使用对象:

class CWD 
{ 
    private $path; 

    public function __construct($path) 
    { 
     $this->setPath($path); 
    } 

    public function setPath($path) 
    { 
     $this->path = $path; 
    } 

    public function getPath() 
    { 
     return $this->path; 
    } 
} 

$directory = new CWD('/path/to/directory'); 

$compress = function($buffer) use ($directory) { 
    // ... 
    $buffer = str_replace('url("', 'url("'.$directory->getPath(), $buffer); 
}; 

然后某处你的代码中你会:

$directory->setPath(); 
echo "whatever css"; 
+0

这可能是一个很好的提示,但路径的目录是不固定的,并取决于需要指令。例如: require_once('dir1/style.css'); - > $ directory ='dir1 /'; require_once('dir2/style.css'); - > $ directory ='dir2 /'; 谢谢你的耐心。 – Danilo 2013-02-13 11:28:52

+0

如果路径要为每个文件保持固定,您可以在include之上指定它们。 $目录= 'DIR1 /'; require_once( 'DIR1/style1.css');然后将“use($ directory)”更改为“use(&$ directory)”以通过引用传递该变量。 – Levi 2013-02-13 14:06:39

+0

@Danilo如果它改变了,你可以改为一个对象。 – 2013-02-13 14:14:26