PHP를 이용해서 간단한 캐싱 클래스를 만들어보았습니다.
여기에선 간단하게 시간을 체크해서 캐시를 재설정할 수 있게 해놓았습니다.
redis 등과 같이 좀 더 고급 기술을 사용하진 않고 단순히 파일 캐싱을 구현하였습니다.
고급 기술을 사용하시거나 좀 더 많은 기능이 필요하실 경우 이미 만들어진 라이브러리를 사용하시는 것이 좋습니다.
참고로 제가 만든 카카오톡 봇의 경우 이 캐싱 클래스를 사용하고 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | <?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 님께 항상 감사드립니다 :)
날씨가 쌀쌀하지만 즐겁고 뜻깊은 휴가 되세요~!