10

我目前正在缩小 JS 文件以提高页面速度。我已经能够找到适用于我几乎所有 js 文件的最简单的方法,除了两个。问题在于我试图在我的网站上实现的 wmd 编辑器的 js 文件。js 文件wmd.jsshowdown.js没有被scripts.php. 我用萤火虫工具检查,在两个文件的响应头中scripts.php都没有包含在最终压缩的 js 文件中。

我压缩这些 js 文件(wmd 和摊牌)并将其合并为一个的过程有什么问题?示例网站

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>
4

2 回答 2

6

我想问题在于语句include("$value.js");echo "\n";
这样,如果包含的 javascript 文件至少包含一个“ <? ”字符串,并且如果您在“php.ini”配置文件中启用了“ short_open_tag ”选项,则 javascript 的一部分代码从 PHP 解释器解析,就好像它是 PHP 代码一样,可能会引发语法错误,因此忽略后续包含。
查看“prettify.js”源代码,我看到有效地存在“<?” 第 471 行的字符串。也许将行更改include("$value.js");echo "\n";readfile("$value.js");echo "\n";应该可以解决问题。

于 2012-08-09T19:54:01.127 回答
1

由于在问题的评论中要求这样做,因此这里是对问题代码的一些评论

功能cacheHeaders

header()通过使用或 函数的第三个参数可以使这个函数更简单、更稳定http_response_code。我强烈建议后者,因为即使使用第三个参数,header()也存在一些问题。有关4.3 <= PHP <= 5.4 和/或更多信息的函数,请参阅此答案。http_response_code

另请注意,有根据 RFC 2822 格式化日期的格式代码,包括正确的时区(而不是强制为 GMT)(r此处查找date

您拥有该代码的页面至少有 5 年的历史,并且即使在那时也可能是为了兼容性而编写的(PHP3!神圣的......!),这并不是真正的错误,但现在是继续前进的时候了。与最初用于其他用途的功能记录不佳或根本没有记录的行为相比,专用功能提​​供了更好的标准合规性和向上兼容性。

输出缓冲区和 HEAD 请求

在处理HEAD请求时,HTTP 服务器必须像处理请求一样处理请求,GET不能返回消息体。这是公认标准的一部分,没有办法。因此,当使用请求执行脚本时,HEADPHP 或 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(),这使得上面的代码仍然是最好的方法。

于 2012-08-18T22:12:10.003 回答