JS文件与PHP文本编辑器的压缩和合并

时间:2012-08-06 21:26:03

标签: php javascript caching

我目前正致力于缩小JS文件以提高页面速度。我已经能够找到最简单的方法,几乎​​所有的js文件,除了两个。问题是我试图在我的网站上实现的wmd编辑器的js文件。 js文件wmd.jsshowdown.js未被scripts.php中的函数压缩和缓存。我使用firebug工具检查,在scripts.php的响应标头中,最终压缩的js文件中都没有包含任何文件。

我压缩这些js文件(wmd& showdown)并将其合并为一个文件的过程有什么问题? EXAMPLE SITE

js / scripts.php-负责js文件的压缩和缓存

<?php
error_reporting(E_ERROR);
// see http://web.archive.org/web/20071211140719/http://www.w3.org/2005/MWI/BPWG/techs/CachingWithPhp
// $lastModifiedDate must be a GMT Unix Timestamp
// You can use gmmktime(...) to get such a timestamp
// getlastmod() also provides this kind of timestamp for the last
// modification date of the PHP file itself
function cacheHeaders($lastModifiedDate) {
    if ($lastModifiedDate) {
        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModifiedDate) {
            if (php_sapi_name()=='CGI') {
                Header("Status: 304 Not Modified");
            } else {
                Header("HTTP/1.0 304 Not Modified");
            }
            exit;
        } else {
            $gmtDate = gmdate("D, d M Y H:i:s \G\M\T",$lastModifiedDate);
            header('Last-Modified: '.$gmtDate);
        }
    }
}

// This function uses a static variable to track the most recent
// last modification time
function lastModificationTime($time=0) {
    static $last_mod ;
    if (!isset($last_mod) || $time > $last_mod) {
        $last_mod = $time ;
    }
    return $last_mod ;
}

lastModificationTime(filemtime(__FILE__));
cacheHeaders(lastModificationTime());
header("Content-type: text/javascript; charset: UTF-8");

ob_start ("ob_gzhandler");

foreach (explode(",", $_GET['load']) as $value) {
    if (is_file("$value.js")) {
        $real_path = mb_strtolower(realpath("$value.js"));
        if (strpos($real_path, mb_strtolower(dirname(__FILE__))) !== false || strpos($real_path, mb_strtolower(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'modules'.DIRECTORY_SEPARATOR)) !== false) {
            lastModificationTime(filemtime("$value.js"));
            include("$value.js");echo "\n";
        } 
    }
}
?>

我调用compressed.js的方式

<script type = "text/javascript" src = "js/scripts.php?build=12345&load=wmd,showdown"></script>

2 个答案:

答案 0 :(得分:6)

我认为问题是陈述include("$value.js");echo "\n";
这样,如果包含的javascript文件至少包含“&lt;?”字符串,并且您在“php.ini”配置文件中启用了“short_open_tag”选项,部分javascript代码正在从PHP解释器中解析,好像它是PHP代码一样,可能会抛出语法错误,因此忽略了后续的包含。
看看“prettify.js”源代码,我看到有效地出现了“&lt;?”第471行的字符串。 将include("$value.js");echo "\n";行更改为readfile("$value.js");echo "\n";可能会解决问题。

答案 1 :(得分:1)

由于这是在问题的评论中提出的,因此以下是对问题代码的一些评论

function cacheHeaders

通过使用header()的第3个参数或函数http_response_code,可以使此函数更简单,更稳定。我强烈建议使用后者,因为即使使用第3个参数,header()也存在一些问题。 See this answer用于http_response_code函数,用于4.3&lt; = PHP&lt; = 5.4和/或更多信息。

另请注意,r格式代码为date,根据RFC 2822格式化日期,包括正确的时区(并且不强制为GMT)(look up here

您拥有该代码的页面至少已有5年的历史,可能是为了兼容而编写的(PHP3!神圣......!),这不是真的错,但现在是时候继续了。专用功能提​​供了更好的标准兼容性和向上兼容性,与最初用于其他功能的功能的记录不良或完全不一致。

输出缓冲区和HEAD请求

处理HEAD请求时,HTTP服务器必须处理请求,就好像它是GET请求,但不得返回邮件正文。这是公认标准的一部分,没有办法解决。因此,当用HEAD请求执行脚本时,PHP或Web服务器(或两者,我真的不知道)将在发送所有标头后立即中止脚本(或者换句话说,当您尝试时输出一些东西)。

现在,当您使用用户空间输出缓冲时,如ob_gzhandler,在执行结束之前可能不会发送标头。这当然仍然通过减少连接数量来实现减少客户端加载时间的目标,但不会减少服务器负载 - 或者更确切地说引入无用的服务器负载 - 并且客户端仍然需要等到脚本完成,这就是标题最后会被发送。

所以要做的就是在所有标题准备就绪后立即“手动”退出脚本。

// setup, header generation, etc.
if($_SERVER['REQUEST_METHOD'] == 'HEAD')
    exit();
ob_start('ob_gzhandler');
// more pretty code, includes and whatnot

如果不使用输出缓冲区,此时还可以flush()和一些输出。但是(根据php手册)win32版本的apache / php实际上并没有在你调用flush()时刷新缓冲区,这使得上面的代码仍然是最好的方法。