TIP게시판

제목 db 쿠키 헬퍼
글쓴이 알브레드 작성시각 2016/06/16 11:44:43
댓글 : 3 추천 : 0 스크랩 : 0 조회수 : 14152   RSS

쿠키를 db에 저장해서 사용해야할 일이 있어서 만들어본 헬퍼입니다.

혹시 필요하신 분이 계실까? 해서 소스 올려봅니다(쑥쓰럽네요 ~~ ;;)

 

--- db_cookie_helper.php ---

<?php defined('BASEPATH') or exit('No direct script access allowed');

/**
 * DB 쿠키 헬퍼
 *
 * @subpackage	Helpers
 * @category	Helpers
 * @author		nina514
 * @link
 */

// ------------------------------------------------------------------------


defined('DC_GLOBAL_COOKIE_NAME') OR define('DC_GLOBAL_COOKIE_NAME', 'DC_COOKIE');  // 전역변수로 사용할 쿠키 변수명
defined('DC_COOKIE_NAME') OR define('DC_COOKIE_NAME', 'DC_COOKIE_ID');             // db cookie 식별 토큰 쿠키명

if (! function_exists('dc_set_cookie')) {
    /**
     * db쿠키 set 함수
     *
     * @param   string  쿠키 key
     * @param   mixed   쿠키 value
     */
    function dc_set_cookie($key, $val = NULL)
    {
        if(empty($key)) {
            throw new Exception('쿠키의 키 값은 필수 요소입니다.');
        }

        $dc_cookie = &$GLOBALS[DC_GLOBAL_COOKIE_NAME];
        $dc_cookie[$key] = $val;
    }
}

if (! function_exists('dc_get_cookie')) {
    /**
     * db쿠키 get 함수
     *
     * @param   string  쿠키 key
     */
    function dc_get_cookie($key)
    {
        if(empty($key)) {
            return NULL;
        }

        if(array_key_exists($key, $GLOBALS[DC_GLOBAL_COOKIE_NAME])) {
            return $GLOBALS[DC_GLOBAL_COOKIE_NAME][$key];
        }

        return NULL;
    }
}


if (! function_exists('dc_delete_cookie')) {
    /**
     * db쿠키 삭제 함수
     *
     * @param   string  쿠키 key
     */
    function dc_delete_cookie($key)
    {
        if(empty($key)) {
            throw new Exception('쿠키의 키 값은 필수 요소입니다.');
        }

        if(array_key_exists($key, $GLOBALS[DC_GLOBAL_COOKIE_NAME])) {
            unset($GLOBALS[DC_GLOBAL_COOKIE_NAME][$key]);
        }
    }
}

if (! function_exists('dc_start_cookie')) {
    /**
     * db쿠키 시작 함수
     *
     */
    function dc_start_cookie()
    {
        // 컨트롤러 인스턴스 가져오기 및 쿠키 모델 로드
        $CI = &get_instance();
        $CI->load->model('Cookie_m');

        // 쿠키 ID GET 및 쿠키 데이터 조회
        $cookie_id = $CI->input->cookie(DC_COOKIE_NAME);
        if(!empty($cookie_id)) {
            $result = $CI->Cookie_m->get_cookie($cookie_id);

            if($result !== FALSE) {
                $GLOBALS[DC_GLOBAL_COOKIE_NAME] = $result;
            }
        }

        if(array_key_exists(DC_GLOBAL_COOKIE_NAME, $GLOBALS) === FALSE) {
            $GLOBALS[DC_GLOBAL_COOKIE_NAME] = array();
        }
    }
}

if (! function_exists('dc_commit_cookie')) {
    /**
     * db쿠키 저장(커밋) 함수
     * redirect를 이용할 경우 redirect전에 꼭 커밋을 해야함 
     *
     */
    function dc_commit_cookie()
    {
        $CI = &get_instance();

        $cookie_id = $CI->input->cookie(DC_COOKIE_NAME);
        if(empty($cookie_id)) {
            $cookie_id = md5(time() . $CI->input->ip_address() . $CI->agent->agent_string());
        }
        $CI->Cookie_m->set_cookie($cookie_id, $GLOBALS[DC_GLOBAL_COOKIE_NAME]);
        $CI->input->set_cookie(DC_COOKIE_NAME, $cookie_id, 30*24*60*60);
    }
}

 

--- Cookie_m.php ---

<?php defined('BASEPATH') or exit('No direct script access allowed');

class Cookie_m extends CI_Model
{

    public function __construct()
    {
        parent::__construct();
    }

    public function set_cookie($key, $data) {
        $sql = "INSERT INTO CI_COOKIES
                (
                    id
                  , agent
                  , ip_address
                  , timestamp
                  , data
                )
                VALUES
                (
                    ?
                  , ?
                  , ?
                  , ?
                  , ?
                )
                ON DUPLICATE KEY
                UPDATE ip_address   = ?
                     , timestamp    = ?
                     , data         = ?";

        $timestamp = time();
        $serialize_data = serialize($data);
        $agent = $this->agent->platform() . '/' . $this->agent->browser();

        $insert_val = array($key, $agent, $this->input->ip_address(), $timestamp, $serialize_data
                          , $this->input->ip_address(), $timestamp, $serialize_data);

        return $this->db->query($sql, $insert_val);
    }

    public function get_cookie($key) {
        $sql = "SELECT data
                  FROM CI_COOKIES
                 WHERE id         = ?
                   AND ip_address = ?
                   AND agent      = ?";

        $agent = $this->agent->platform() . '/' . $this->agent->browser();
        $result = $this->db->query($sql, array($key, $this->input->ip_address(), $agent));

        if($result->num_rows() === 0) {
            return FALSE;
        }
        else {
            return unserialize($result->result_array()[0]['data']);
        }
    }
}

 

--- 테이블 생성 쿼리 ---

CREATE TABLE `CI_COOKIES` (
	`id` VARCHAR(40) NOT NULL,
	`agent` VARCHAR(150) NOT NULL,
	`ip_address` VARCHAR(45) NOT NULL,
	`timestamp` INT(10) UNSIGNED NOT NULL DEFAULT '0',
	`data` BLOB NOT NULL,
	PRIMARY KEY (`id`)
)

 

제가 작성한 코드는 위와 같고요.

사용법은 헬퍼 파일과 모델 파일을 생성하시고 위 소스를 붙여넣어주세요. 그리고 sql문으로 테이블을 생성합니다.(테이블 스크립트는 CI 세션 테이블과 동일하고 agent컬럼만 추가되었습니다.)

ci에서 헬퍼를 로드하시고, db cookie를 이용하실 구간에서 dc_start_cookie() 함수를 호출합니다.(이때 쿠키에 사용자 구분 토큰을 생성하여 로컬 쿠키에 저장합니다. 그리고 생성된 토큰으로 테이블을 조회하여 데이터를 가져옵니다.) db cookie 조작함수 dc_set_cookie(), dc_get_cookie(), dc_delete_cookie() 함수로 db cookie를 조작한 뒤 마지막으로 dc_commit_cookie() 함수를 호출하여 쿠키를 커밋하시면 cookie가 db에 저장됩니다.

아 저같은 경우에는 dc_start_cookie(), dc_commit_cookie()함수를 hook에서 호출하고 컨트롤러에서 get, set, delete함수를 이용하여 조작하는 방식으로 사용을 하고있습니다. 주의점은 redirect하실때는 redirect전에 dc_commit_cookie() 함수를 호출하여야 redirect된 컨트롤러에서 정상 반영된 쿠키가 보인다는 점입니다.

// 컨트롤러가 인스턴스화 되고 실행되기 전에 실행되는 훅
$hook['post_controller_constructor'][] = function() {
    dc_start_cookie();
};

// 컨트롤러 실행이 모두 완료되었을때 실행되는 훅
$hook['post_controller'][] = function() {
    dc_commit_cookie();
};

 

위 과정이 사용법 전부입니다. 설명을 잘 못쓴것 같아 많이 부끄럽네요. 다음에도 필요해서 만든 소스들 많이 올릴 수 있도록 노력해보겠습니다.

감사합니다^^

태그 cookie,쿠키,db cookie
 다음글 Apache Memory Leak 대응방법 (3)
 이전글 위젯 라이브러리(?) 입니다. (1)

댓글

한대승(불의회상) / 2016/06/16 16:58:44 / 추천 1

훅을 이용해서 쿠키를 DB에 저장 하는군요.

좋은 코드 감사 합니다. ^^

수야디벨 / 2016/07/05 09:30:34 / 추천 1
역시 숨은 고수는 많아요 ! 눈 호강 잘하고 갑니다 :) 
알브레드 / 2016/07/14 00:06:55 / 추천 0

@수야디벨

과찬이십니다. :)

제 소스가 조금이나마 다른 분들께 도움이 되었으면 좋겠네요 ㅎㅎ