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 |