코드
2018.12.06 13:41

[PHP] 간단한 캐싱 클래스

조회 수 818 추천 수 1 댓글 3
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form
라이선스 MIT

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();



Who's humit

profile

Study For Us Hosting 1기 모니터링 관리자 (16.12.01 ~ 17.01.08.)

C++, Python, PHP를 주로 사용하며 알고리즘, DL, 해킹 쪽에 관심이 있습니다.

휴학생입니다.

티스토리 블로그 : http://humit.tistory.com/

카카오톡 봇 : http://pf.kakao.com/_Efrbu/chat

지식인 프로필 : https://kin.naver.com/profile/jhjang1005

  • profile
    이니스프리 2018.12.06 14:28

    요새 그러지 않아도 캐시에 관심이 많았는데 좋은 스크립트 올려주셔서 감사합니다 ^-^

    올려주신 스크립트가 일종의 파일캐시(디스크캐시)인 것이죠?

    덕분에 파일캐시의 구조에 대해 조금이나마 이해하게 되었네요~


    그누보드가 세션 등 처리에 있어 상대적으로 캐시 친화적이지 않고

    게다가 XE/라이믹스에는 슈퍼캐시 모듈이 있기 때문에,

    양자 간에 TTFB나 감당할 수 있는 동접자 수에서 차이가 발생하고

    그러한 결과 간접적으로 SEO에서도 불이익이 발생한다고 알고 있네요 ㅠㅠ


    제가 Redis를 사용해보려고 했는데 그누보드/아미나 최신버전에 PHP 7 환경에서

    제대로 작동하는 공개된 플러그인이 아마도 없는 것 같더군요 ㅜㅜ


    만약 글이 자주 올라오지 않는 환경에서 최신글 위젯 등을 효율적으로 캐싱하려면

    캐시 만료시간을 아주 길게 잡는 대신에

    새 글을 작성하면 캐시를 갱신하는 방식으로 사용하면 되겠죠?


    좋은 자료 올려주신 덕분에 열심히 공부해보겠습니다~

    humit 님께 항상 감사드립니다 :)

    날씨가 쌀쌀하지만 즐겁고 뜻깊은 휴가 되세요~!

  • profile
    title: 황금 서버 (30일)humit 2018.12.06 18:47
    네 일종의 파일 캐시라고 생각하시면 됩니다 ㅎㅎ
  • ?
    포인트 폭탄+ 2018.12.06 18:47
    humit님 축하합니다.
    추가로 200포인트만큼 포인트 폭탄+를 받았습니다.

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
38 코드 잘못 쓰면 컴퓨터가 날아가는 코드 29 제르엘 2018.07.08 1016
37 코드 매우 특이한 버그 9 title: 대한민국 국기gimmepoint 2018.06.05 720
36 내가 만든 merge sort 3 title: 대한민국 국기gimmepoint 2018.05.17 528
35 코드 내가 만든 함수 모음집 2 title: 대한민국 국기gimmepoint 2018.05.12 528
34 코드 내가 만든 사칙연산 계산기 title: 대한민국 국기gimmepoint 2018.05.11 621
33 코드 내가 만든 함수 모음집 4 title: 대한민국 국기gimmepoint 2018.05.08 520
32 코드 클라이언트단에서 이미지 리사이징 6 file 네모 2018.05.06 1154
31 코드 HEX를 RGB로, RGB를 HEX로 바꾸는 PHP 코드 1 네모 2018.05.05 672
30 코드 c 이진트리 전,중,후위 알고리즘 2 title: 대한민국 국기gimmepoint 2018.04.24 642
29 코드 html 초보가 만든 자소서 4 title: 대한민국 국기gimmepoint 2018.04.21 730
28 코드 Hello, World!를 출력해보자 18 네모 2018.04.21 661
27 코드 아주 간단한 기초 C++ 6 제르엘 2018.04.21 567
26 코드 미완성 받아쓰기 (C) title: 대한민국 국기gimmepoint 2018.04.20 565
25 코드 Cmd 에서 서비스 시작 / 종료하기 1 ProjectSE 2018.02.18 691
24 코드 CMD로 로컬 연결 고정 IP 설정하기 1 title: 황금 서버 (30일)humit 2018.02.06 1092
23 코드 컴퓨터의 uuid 얻기 5 title: 황금 서버 (30일)humit 2018.01.28 1220
22 코드 유튜브에 약간의 기능을 추가 해주는 크롬 확장 프로그램. 11 file Hanam09 2018.01.26 1076
21 코드 사이트 서버 이전 (또는 미러링 사이트 구축) 쉽게하는 스크립트 1 NoYeah 2018.01.14 1027
20 코드 새 글 자동 댓글 스크립트 (AutoHotkey) 9 이니스프리 2017.11.26 3561
19 코드 파이썬을 이용한 텔레그램 새 글 알림 (허접합니다) 4 이니스프리 2017.11.19 2516
Board Pagination Prev 1 2 3 4 Next
/ 4