Передача браузеру файлов js и css, сжатыми с помощью gzip на php

Важно соблюсти следующие моменты

  1. Отдавать gzip содержимое браузеру, только если он заявил о поддержке gzip-контента(остальным отдавать несжатое содержимое)
  2. Отдавать ошибку 404 Not Found, если такого файла нет
  3. Отдавать заголовок Last-Modified, адекватный дате последнего изменения файла
  4. Отдавать заголовок 304 Not Modified, если полученная в заголовке If-Modified-Since дата старше даты изменения файла(кэш устарел)
  5. Игнорировать QUERY_STRING(то, что в запросе после знака вопроса, включая его самого)

.htaccess

RewriteEngine on
RewriteRule ^(.*)\.css$ /gzip.php [L]
RewriteRule ^(.*)\.js$ /gzip.php [L]

gzip.php

<?php
    // Определяем имя файла, который передаём
    $filename = $_SERVER['DOCUMENT_ROOT'].$_SERVER['REQUEST_URI'];

    // Отрезаем query-string(то, что после вопроса)
    $filename = preg_replace("/^(.*)\?.*$/", "$1", $filename);

    // Опредеяем расширение файла (по)
    $ext = preg_replace("/^.*\.(.*)$/", "$1", $filename);

    // Определяем content-type для заголовка
    switch($ext){
        case "js":
            $content_type = "application/javascript";
        break;
        case "css":
            $content_type = "application/css";
        break;
        case "html":
            $content_type = "text/html";
        break;
        case "htm":
            $content_type = "text/html";
        break;
        case "txt":
            $content_type = "text/plain";
        break;
    }

    // Если такого файла нет - посылаем 404-ю ошибку
    if(!file_exists($filename)){
        header("HTTP/1.1 404 NotFound");
        die;
    }

    // Получаем информацию о файле(в том числе дату последнего изменения)
    $stat = stat($filename);

    // Если браузер сообщил о том, что этот файл есть у него в кэше,
    // с определённой датой последнего изменения, и если дата последнего изменения
    // файла не новее, чем дата кэша - посылаем 304 заголовок и не маимся со сжатием
    if(
        isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
    ){
        $date = date_parse_from_format  ( "D, d M Y H:i:s"  , $_SERVER['HTTP_IF_MODIFIED_SINCE']);
        $if_mod_since = gmmktime($date['hour'], $date['minute'], $date['second'],$date['month'], $date['day'],$date['year']);
        if($if_mod_since - $stat['mtime']>=0){    
            header("HTTP/1.1 304 Not Modified");
            die;
        }
    }

    // Отправляем дату последнего изменения файла
    $lastmod = gmdate("D, d M Y H:i:s", $stat['mtime'])." GMT";
    header("Last-Modified: $lastmod");

    // Если в заголовках браузер подтвердил, что поддерживает gzip-сжатие, то
    // отправляем ему сжатое содержимое
    if(isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], "gzip")!==false){
        $content = gzencode(file_get_contents($filename));
        header("Content-Encoding: gzip");
    }
    // Иначе отправляем несжатое содержимое
    else{
        $content = file_get_contents($filename);
    }

    // Отправляем заголовок типа содержимого
    header("Content-Type: $content_type");
    // Отправляем содержимое
    echo $content;
?>

Добавить комментарий