Сжатие и слияние файлов JS с PHP-текстовым редактором

В настоящее время я работаю над минимизацией JS файлов для улучшения скорости страницы. Я смог найти самый простой метод, который работает почти со всеми моими файлами js, за исключением двух. Проблема связана с файлами js для редактора wmd, который я пытаюсь реализовать на моем сайте. Файлы js wmd.js и showdown.js не являются сжатием и кешем с помощью функции в scripts.php. Я проверил с помощью средства firebug, в заголовке ответа scripts.php ни один файл не включен в окончательный сжатый файл js.

В чем проблема с моим процессом сжатия этих js файлов (wmd и showdown) и объединения их в один? ПРИМЕР САЙТА

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";
        } 
    }
}
?>

То, как я вызываю compress.js

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

Ответ 1

Я полагаю, что проблема заключается в утверждении include("$value.js");echo "\n";
Таким образом, если включенный файл javascript содержит по крайней мере строку " <?", и если вы включили " short_open_tag" в вашем конфигурационном файле "php.ini", часть кода javascript анализируется с помощью интерпретатора PHP, как если бы это был PHP-код, вероятно, бросая синтаксическую ошибку и, следовательно, игнорируя последующие включения. Глядя на исходный код "prettify.js", я видел, что эффективно присутствует "<?" строка в строке 471. Может быть, изменение строки include("$value.js");echo "\n"; до readfile("$value.js");echo "\n"; должно решить проблему.

Ответ 2

Поскольку это было запрошено в комментариях к вопросу, вот некоторые комментарии к коду вопроса

функция cacheHeaders

Эта функция может быть упрощена и более стабильной, используя 3-й параметр header() или функцию http_response_code. Я настоятельно рекомендую последнее, так как даже с третьим параметром header() имеет некоторые проблемы. См. этот ответ для функции http_response_code для 4.3 <= PHP <= 5.4 и/или более информации.

Также обратите внимание, что есть формат кода r для date, который форматирует дату в соответствии с RFC 2822, включая правильный часовой пояс (и не принудительно GMT) (найдите здесь)

Страница, на которой у вас есть этот код, составляет как минимум 5 лет и, вероятно, была написана для совместимости даже тогда (PHP3! Holy...!), это не совсем так, но пришло время двигаться дальше. Выделенные функции обеспечивают лучшую совместимость стандартов и повышающую совместимость по сравнению с плохой или вообще не документированным поведением функций, которые изначально были предназначены для чего-то другого.

выходной буфер и запрос HEAD

При обработке запроса HEAD HTTP-сервер должен обрабатывать запрос так, как если бы он был запросом GET, а не должен возвращать тело сообщения. Это часть принятого стандарта, и пути нет. Поэтому, когда script выполняется с запросом HEAD либо PHP, либо веб-сервер (или оба, я, честно говоря, не знаю), прервет script, как только будут отправлены все заголовки (или, другими словами, когда вы пытаетесь вывести что-то).

Теперь, однако, когда вы используете буферизацию вывода пользовательского пространства, например ob_gzhandler, заголовки могут не отправляться до конца выполнения. Это, конечно же, позволяет достичь цели сокращения времени загрузки клиента за счет сокращения количества подключений, но не снижает нагрузку на сервер - или, скорее, вводит бесполезную нагрузку на сервер, - и клиенту все равно придется ждать, пока ваш script не завершится, а это произойдет, когда заголовки, наконец, будут отправлены.

Таким образом, путь, выходящий из script "вручную", сразу после того, как все ваши заголовки готовы и установлены.

// 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(), что делает вышеприведенный код еще лучшим способом.