작은숲:위키노트/아파치 mod_deflate 모듈 등의 웹 서버에서 제공하는 압축 전송 모듈과는 달리 PHP의 zlib 모듈을 사용할 때는 PHP 파일만 압축해서 전송한다. 그래서 서버 전체적으로 보면 감소하는 트래픽의 양이 기대한 것만큼 크지 않다. 웹 서버의 압축 전송 모듈을 사용할 수 없을 때 CSS자바스크립트 등도 압축 전송하려면 이러한 파일을 전송할 때 PHP를 통해 압축한 후 전송하도록 한다.

압축 방법 선택

작은숲:위키노트/PHP 압축 전송을 위해 두 가지 방법을 선택할 수 있다.

  1. php.ini.htaccess 파일, 혹은 PHP 파일에서 zlib.output_compression 설정
  2. PHP 파일에서 ob_gzhander() 함수 사용

가능하다면 첫 번째 방법을 사용하도록 한다.

아파치 mod_rewrite 모듈 사용

기존의 소스 파일을 최대한 수정하지 않도록 하기 위해 작은숲:위키노트/아파치 mod_rewrite 모듈을 사용한다. 아래 내용을 가상 호스트 설정이나 .htaccess 파일에 추가한다.

<IfModule rewrite_module>
    RewriteEngine On
    RewriteRule ^(.*\.js) gzip.php?type=js&file=$1
    RewriteRule ^(.*\.css) gzip.php?type=css&file=$1
</IfModule>

이 설정은 자바스크립트CSS 파일을 gzip.php를 통해서 보내도록 한다.

PHP 스크립트 작성

아래 내용으로 다른 파일을 압축 전송하는 PHP 스크립트를 만든다. 파일 이름은 Rewrite 설정에서 쓴 이름을 사용한다.

<?php
// check that zlib compression is enabled
if (!ini_get('zlib.output_compression')) { die(); }
 $allowed = array('css', 'js'); // set array of allowed file types to prevent abuse
 // check for request variable existence and that file type is allowed
if (isset($_GET['file']) && isset($_GET['type']) && in_array(substr($_GET['file'], strrpos($_GET['file'], '.') + 1), $allowed)) {
    $data = file_get_contents(dirname(__FILE__) .'/'. $_GET['file']); // grab the file contents
     $etag = '"'. md5($data) .'"'; // generate a file Etag
    header('Etag: '. $etag); // output the Etag in the header
     // output the content-type header for each file type
    switch ($_GET['type']) {
        case 'css':
            header("Content-Type: text/css; charset: UTF-8");
            break;
         case 'js':
            header("Content-Type: text/javascript; charset: UTF-8");
            break;
    }
     header('Cache-Control: max-age=300, must-revalidate'); //output the cache-control header
    $offset = 60 * 60;
    $expires = 'Expires: '. gmdate('D, d M Y H:i:s', time() + $offset) .' GMT'; // set the expires header to be 1 hour in the future
    header($expires); // output the expires header
     // check the Etag the browser already has for the file and only serve the file if it is different
    if ($etag == $_SERVER['HTTP_IF_NONE_MATCH']) {
        header('HTTP/1.1 304 Not Modified');
        header('Content-Length: 0');
    } else {
        echo $data;
    }
}?>

여기까지 설정이 제대로 됐다면 앞으로 클라이언트가 요청하는 CSS와 자바스크립트 파일도 PHP 파일처럼 압축해서 전송할 수 있다. 만약 다른 파일 형식도 추가하고 싶다면 Rewrite 설정과 PHP 스크립트에 파일 형식을 추가하면 된다. 조금 번거롭지만 이렇게 하면 작은숲:위키노트/아파치 mod_deflate 모듈처럼 대부분의 텍스트 형식의 파일들을 압축 전송할 수 있다. 그래도 역시 가장 좋은 방법은 작은숲:위키노트/아파치 mod_deflate 모듈과 같은 웹 서버의 압축 전송 모듈을 사용하는 것이다.

출처

참고