Извините за задержку - это - напряженная неделя для меня.
Предположения:
.htaccess
находится в том же файле как compress.php
static
подкаталогЯ запустил свое решение с установки следующих директив в .htaccess:
RewriteEngine on
RewriteRule ^static/.+\.(js|ico|gif|jpg|jpeg|png|css|swf)$ compress.php [NC]
Требуется, что Ваш поставщик позволяет Вам переопределять mod_rewrite
опции в .htaccess
файлы. Затем сам compress.php файл может быть похожим на это:
<?php
$basedir = realpath( dirname($_SERVER['SCRIPT_FILENAME']) );
$file = realpath( $basedir . $_SERVER["REQUEST_URI"] );
if( !file_exists($file) && strpos($file, $basedir) === 0 ) {
header("HTTP/1.0 404 Not Found");
print "File does not exist.";
exit();
}
$components = split('\.', basename($file));
$extension = strtolower( array_pop($components) );
switch($extension)
{
case 'css':
$mime = "text/css";
break;
default:
$mime = "text/plain";
}
header( "Content-Type: " . $mime );
readfile($file);
Необходимо, конечно, добавить больше типов пантомимы к оператору переключения. Я не хотел делать иждивенца решения на pecl fileinfo
расширение или любые другие волшебные библиотеки обнаружения типа пантомимы - это - самый простой подход.
Что касается обеспечения сценария - я делаю перевод в реальный путь в файловой системе, таким образом, не взломанной '../../../etc/passwd' или другие пути к файлам сценария оболочки, не проходит.
Это
$basedir = realpath( dirname($_SERVER['SCRIPT_FILENAME']) );
$file = realpath( $basedir . $_SERVER["REQUEST_URI"] );
отрывок. Хотя я вполне уверен большинство путей, которые находятся в другой иерархии, чем $basedir будет обработан Apache, прежде чем они даже достигнут сценария.
Также я проверяю, ли получающийся путь в дереве каталогов сценария. Добавьте заголовки для управления кэшем как pilif предложенный, и у Вас должно быть рабочее решение Вашей проблемы.
Что я делаю:
js
и таблицы стилей в a css
dir, соответственно.В конфигурации Apache я добавляю директивы как так:
<Directory /data/www/path/to/some/site/js/>
AddHandler application/x-httpd-php .js
php_value auto_prepend_file gzip-js.php
php_flag zlib.output_compression On
</Directory>
<Directory /data/www/path/to/some/site/css/>
AddHandler application/x-httpd-php .css
php_value auto_prepend_file gzip-css.php
php_flag zlib.output_compression On
</Directory>
gzip-js.php в js
каталог похож на это:
<?php
header("Content-type: text/javascript; charset: UTF-8");
?>
… и gzip-cs.php в css
каталог похож на это:
<?php
header("Content-type: text/css; charset: UTF-8");
?>
Это не может быть самым изящным решением, но это несомненно - простое, которое требует немногих изменений и работ хорошо.
что когда-либо Вы делаете, быть осторожными относительно кэширования на стороне клиента:
Браузеры действительно все сортируют приемов, чтобы попытаться минимизировать bandwith и существует много путей в протоколе HTTP, чтобы сделать это, со всеми из которых имеет дело апач - если Вы просто служите локальному файлу.
Если Вы не, то это - Ваша ответственность.
Взгляните, по крайней мере, на Завершающий тег и механику If-Modified-Since, которые поддерживаются всеми текущими браузерами и, кажется, самый устойчивый способ запросить сервер для обновленного содержания.
Возможный способ служить файлу CSS браузерам с помощью If-Modified-Since-Header является чем-то вроде этого (пустые заголовки для выключения любых заголовков некэширования, которые PHP отправляет на значение по умолчанию):
$p = 'path/to/css/file'
$i = stat($p);
if ($_SERVER['HTTP_IF_MODIFIED_SINCE']){
$imd = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ( ($imd > 0) && ($imd >= $i['mtime'])){
header('HTTP/1.0 304 Not Modified');
header('Expires:');
header('Cache-Control:');
header('Last-Modified: '.date('r', $i['mtime']));
exit;
}
}
header('Last-Modified: '.date('r', $i['mtime']));
header('Content-Type: text/css');
header('Content-Length: '.filesize($p));
header('Cache-Control:');
header('Pragma:');
header('Expires:');
readfile($p);
Код будет использовать if-modified-since-header, который браузер отправляет в проверку, если фактический файл на сервере изменился начиная с даты браузер дал. Если так, файл отправляется, иначе, 304, Не Измененные, возвращается, и браузер не должен повторно загружать целое содержание (и если это достаточно интеллектуально, это имеет в наличии проанализированный CSS в памяти также).
Существует другой механик, включающий сервер, отправляющий уникальный Заголовок завершающего тега за каждой частью содержания. Клиент отправит ту спину с помощью заголовка If-None-Match, позволяющего сервер решить не только в день последнего изменения, но также и на самом содержании.
Это просто делает код более сложным, хотя, таким образом, я пропустил его. FF, IE и Opera (вероятно, Safari также) все отправляют заголовок If-Modified-Since, когда они получают содержание с Измененным в последний раз присоединенным заголовком, таким образом, это хорошо работает.
Также имейте в виду, что определенные версии IE (или Время выполнения JScript он использует) все еще имеют проблемы с GZIP-переданным содержанием.
О. И я знаю, что это не часть вопроса, но также - Acrobat в некоторых версиях. У меня были случаи и случаи белых экранов при обслуживании PDFs с кодированием передачи gzip.
Можно попытать счастья с mod_rewrite.
Создайте сценарий, который берет локальное статическое имя файла, как введено, через например. $_SERVER['QUERY_STRING']
и выводы это в сжатой форме. Многие поставщики не позволяют настраивать mod_rewrite
с .htaccess
файлам или отключили его полностью все же.
Если Вы не использовали, переписывают прежде, я рекомендую руководству хорошего новичка, как, вероятно, этот. Таким образом, можно сделать апачское перенаправление всеми запросами на статический файл к сценарию PHP. style.css будет перенаправлен к compress.php? style.css, например.
Как всегда быть чрезвычайно осторожными относительно входа Вы принимаете, или Вы имеете XSS
используйте на руках!
Вместо gzipping на лету, когда пользователи запрашивают CSS и JavaScript файлы, вы можете gzip их заранее. Пока Apache обслуживает их с правильными заголовками, вы золотой.
Например, в Mac OS X, gzipping файла в командной строке так же просто, как:
gzip -c styles.css > styles-gzip.css
Может быть, это не тот тип рабочего процесса, который работает на вас.
.