본문 바로가기
프로그래밍/PHP

PHP 세션

by Joshbla 2025. 7. 24.

PHP 세션 정리

세션(Session)이란?

세션(Session)은 사용자의 상태 정보를 서버 측에 저장하는 방식입니다. 예를 들어 로그인 정보, 장바구니 내역, 사용자 설정값 등이 세션을 통해 유지됩니다. PHP에서는 기본적으로 `$_SESSION` 전역 배열을 통해 세션 값을 저장하고 불러올 수 있습니다.

 

PHP의 기본 세션 저장 방식

PHP는 기본적으로 세션 데이터를 파일에 저장합니다. 세션이 시작되면 고유한 세션 ID가 발급되고, 사용자의 브라우저에는 PHPSESSID 쿠키로 전달됩니다. 이 ID를 기반으로 서버는 임시 폴더(예: /tmp)에 sess_{세션ID} 형태의 파일을 생성하여 데이터를 보관합니다.

기본 세션 설정은 다음과 같이 확인할 수 있습니다.

ini_get('session.save_handler');// 기본값: files
ini_get('session.save_path');// 기본값: /tmp

 

파일 세션의 한계점

파일 기반 세션은 간단하고 빠르지만, 다음과 같은 단점이 있습니다.

 

1. 로드밸런싱 서버 환경에서 세션 공유가 어렵습니다.

2. 파일 잠금으로 인해 동시 접근 문제가 발생할 수 있습니다.

3. 세션 데이터 통계나 로그 분석이 어렵습니다.

 

DB세션의 장점

 

1. 로드밸런싱 환경에서 세션 공유 가능
→ 여러 웹 서버를 사용하는 환경에서 모든 서버가 공통 DB를 통해 같은 세션 데이터를 읽고 쓸 수 있습니다.

2. 세션 모니터링 및 디버깅 용이
→ DB에 저장된 세션 정보를 SQL로 직접 조회 가능합니다. 로그인 사용자 추적이나 세션 상태 파악이 쉽습니다.

3. 장애 복구 및 안정성
→ 파일 세션보다 유실 위험이 낮고, DB 백업을 통해 세션도 함께 보호 가능합니다.

4. 보안 강화와 확장성
→ 사용자 IP, 디바이스 정보, 로그인 이력 등을 함께 저장 가능하며 관리자 세션 별도 관리도 쉽습니다.

5. 커스터마이징이 자유로움
→ 세션 구조를 필요에 맞게 설계 가능합니다. (예: 로그인 실패 횟수, 브라우저 정보 등 추가 저장)

 

 

DB 세션으로 전환하기

커스텀 세션 핸들러 구현

PHP에서는 session_set_save_handler() 함수를 이용해 커스텀 세션 핸들러를 정의할 수 있습니다. 다음은 주요 함수들입니다.

  • sess_open: 세션 열기 (초기화)
  • sess_close: 세션 닫기
  • sess_read: 세션 데이터 읽기
  • sess_write: 세션 데이터 저장
  • sess_destroy: 세션 삭제
  • sess_gc: 오래된 세션 정리

작성한 세션 핸들러를 등록한 후, session_start()로 세션을 시작하면 데이터가 파일이 아닌 DB에 저장됩니다.

 

예시)

ini_set( 'session.cookie_httponly', 1 ); // 세션 쿠키에 JavaScript 접근을 막음
ini_set( 'session.use_only_cookies', 1 ); // 오직 쿠키로만 세션 ID를 전달하게 만듦

function sess_open($save_path, $session_name) {
    return true;
}

function sess_close() {
    return true;
}

function sess_read($key) {
    $key = mysql_real_escape_string($key);
    $result = mysql_query("SELECT data FROM Sessions WHERE key = '$key'");
    if ($row = mysql_fetch_assoc($result)) {
        return $row['data'];  // 이게 $_SESSION 으로 복원된다
    }
    return '';  // 세션 없음
}

function sess_write($key, $data) {
    $key = mysql_real_escape_string($key);
    $data = mysql_real_escape_string($data); // serialize된 문자열
    $time = time();
    mysql_query("REPLACE INTO Sessions (key, data, time) VALUES ('$key', '$data', $time)");
    return true;
}

function sess_destroy($key) {
    $key = mysql_real_escape_string($key);
    mysql_query("DELETE FROM Sessions WHERE key = '$key'");
    return true;
}

function sess_gc($maxlifetime) {
    $old = time() - $maxlifetime;
    mysql_query("DELETE FROM Sessions WHERE time < $old");
    return true;
}

// 세션핸들러 등록 및 시작
session_set_save_handler(
    "sess_open",
    "sess_close",
    "sess_read",
    "sess_write",
    "sess_destroy",
    "sess_gc"
);

// 세션 만료 시간 설정 (예: 30분)
ini_set('session.gc_maxlifetime', 1800);

// 쿠키도 같은 만료 시간으로 설정하면 더 안정적이다
session_set_cookie_params(1800);

register_shutdown_function('session_write_close');
session_start();

 

이렇게 등록하고 실행하면 앞으로 세션정보가 DB에 등록되며

가비지콜렉터가 sess_gc 함수를 일정시간마다 실행하여 오래된 세션을 제거한다.

 

$_SESSION['user_name']     = '코딩하는조씨';
$_SESSION['user_id']     = 'josh';

위와 같이 세션에 등록하면 데이터가 자동으로 serialize되어 

a:2:{s:9:"user_name";s:18:"코딩하는조씨";s:8:"user_id";s:4:"josh";}

이렇게 DB에 저장이 되고 세션을 불러올 때는 자동으로 unserialize되어 배열로 값을 가져온다.

$_SESSION = [
'user_name' => '코딩하는조씨', 
'user_id' => 'josh'
]

 

 

주의사항 및 팁

  • session_write_close()를 register_shutdown_function()으로 등록하면, 스크립트 종료 시 세션 데이터 저장을 보장할 수 있습니다.
  • 세션 데이터는 serialize() 되어 저장되며, VARCHAR 타입 컬럼에 저장 시 길이 초과에 유의해야 합니다.
  • 세션 GC(Garbage Collection)는 PHP 설정에 따라 확률적으로 수행되므로, 필요시 직접 호출하는 것도 고려해볼 수 있습니다.
  • 환경에 따라 파일 기반 세션 대신 DB 세션이 더 적합할 수 있습니다. 특히 다중 서버 환경, 사용자 추적, 세션 보안 강화를 고려할 때는 커스텀 세션 핸들러 구현을 고려해보면 좋을 것 같습니다.

'프로그래밍 > PHP' 카테고리의 다른 글

PHP 설치부터 실행까지  (1) 2025.07.22
PHP 개요  (1) 2025.07.20