PHP를 이용해서 간단한 캐싱 클래스를 만들어보았습니다.
여기에선 간단하게 시간을 체크해서 캐시를 재설정할 수 있게 해놓았습니다.
redis 등과 같이 좀 더 고급 기술을 사용하진 않고 단순히 파일 캐싱을 구현하였습니다.
고급 기술을 사용하시거나 좀 더 많은 기능이 필요하실 경우 이미 만들어진 라이브러리를 사용하시는 것이 좋습니다.
참고로 제가 만든 카카오톡 봇의 경우 이 캐싱 클래스를 사용하고 있습니다.
<?php class Cache { // 실제 파일이 저장된 폴더 private $real_file_dir; // 캐시 파일이 저장될 폴더 private $cache_file_dir; // 캐시 만료 시간 (초 단위) private $timeout; public function __construct($real_dir, $cache_dir, $timeout) { $this->real_file_dir = $real_dir; $this->cache_file_dir = $cache_dir; $this->timeout = $timeout; // 캐시 폴더가 존재하지 않는 경우 폴더 생성 if(!file_exists($cache_dir)) { mkdir($cache_dir, 0777, TRUE); } } // 파일 출력 가져오기 private static function _get_file_data($filepath, $render = FALSE) { if(!file_exists($filepath)) { return NULL; } if($render === TRUE) { // PHP 코드를 실행한 결과를 반환 ob_start(); include $filepath; $content = ob_get_clean(); return $content; } else { // 그냥 파일을 읽어서 나온 결과를 반환 return file_get_contents($filepath); } } // 캐시 파일 이름 생성 (기존 이름에서 확장자 부분을 제거하고 앞쪽에 cache_를 붙인다) private static function _convert_cache_filename($filename) { return 'cache_' . substr($filename, 0, strrpos($filename, '.')); } // 실제 파일이 위치한 경로 private function _get_real_file_path($filename) { return $this->real_file_dir . '/' . $filename; } // 캐시 파일이 위치한 경로 private function _get_cache_file_path($filename) { return $this->cache_file_dir . '/' . $filename; } // 실제 파일 출력 가지고 오기 private function _get_real_file_data($filename) { return self::_get_file_data($this->_get_real_file_path($filename), TRUE); } // 캐시 파일 내용 가지고 오기 private function _get_cache_file_data($filename) { return self::_get_file_data($this->_get_cache_file_path($filename), FALSE); } // 캐시 파일이 생성된 시간 가지고 오기 private function _get_cache_time($filename) { $filepath = $this->_get_cache_file_path($filename); if(!file_exists($filepath)) { return 0; } else { return filemtime($filepath); } } // 캐시 파일 생성하기 private function _create_cache_file($filename) { $cache_filename = $this->_convert_cache_filename($filename); $cache_filepath = $this->_get_cache_file_path($cache_filename); $content = $this->_get_real_file_data($filename); $f = fopen($cache_filepath, "w"); fwrite($f, $content); fclose($f); return $content; } // 캐시 파일들 삭제하기 public function clear_cache() { $cache_files = glob($this->cache_file_dir . '/*'); foreach ($cache_files as $file) { if(is_file($file)) { unlink($file); } } } // 파일 내용 읽어오기. 캐싱이 된 경우 캐시 파일을, 실패한 경우에는 캐시 파일을 생성하고 해당 내용을 출력 public function get_content($filename, $timeout = 0) { if($timeout === 0) $timeout = $this->timeout; $cache_filename = self::_convert_cache_filename($filename); $cache_time = $this->_get_cache_time($cache_filename); $current_time = time(); // timeout이 초과한 경우 캐시 파일 재생성 if($current_time - $cache_time > $timeout) { return $this->_create_cache_file($filename); } else { return $this->_get_cache_file_data($cache_filename); } } } // 60초 캐시 클래스 생성 $cache = new Cache(__DIR__ . '/real/file/path', __DIR__ . '/cache/file/path', 60); // file.php를 캐싱해서 읽어오기 (기본 값 사용) $result = $cache->get_content('file.php'); echo $result; // file_10s.php를 캐싱해서 읽어오기 (10초) $result = $cache->get_content('file_10s.php', 10); echo $result; // 캐시 삭제 $cache->clear_cache();
요새 그러지 않아도 캐시에 관심이 많았는데 좋은 스크립트 올려주셔서 감사합니다 ^-^
올려주신 스크립트가 일종의 파일캐시(디스크캐시)인 것이죠?
덕분에 파일캐시의 구조에 대해 조금이나마 이해하게 되었네요~
그누보드가 세션 등 처리에 있어 상대적으로 캐시 친화적이지 않고
게다가 XE/라이믹스에는 슈퍼캐시 모듈이 있기 때문에,
양자 간에 TTFB나 감당할 수 있는 동접자 수에서 차이가 발생하고
그러한 결과 간접적으로 SEO에서도 불이익이 발생한다고 알고 있네요 ㅠㅠ
제가 Redis를 사용해보려고 했는데 그누보드/아미나 최신버전에 PHP 7 환경에서
제대로 작동하는 공개된 플러그인이 아마도 없는 것 같더군요 ㅜㅜ
만약 글이 자주 올라오지 않는 환경에서 최신글 위젯 등을 효율적으로 캐싱하려면
캐시 만료시간을 아주 길게 잡는 대신에
새 글을 작성하면 캐시를 갱신하는 방식으로 사용하면 되겠죠?
좋은 자료 올려주신 덕분에 열심히 공부해보겠습니다~
humit 님께 항상 감사드립니다 :)
날씨가 쌀쌀하지만 즐겁고 뜻깊은 휴가 되세요~!