PHP 세션 · 1 min read · Dec 27, 2025
PHP 세션 데이터가 Debian(및 Ubuntu)에서 사용자 정의 세션 관리를 사용할 때 삭제되지 않음
Debian 시스템에서는 (내가 아는 한, 이는 Ubuntu에도 적용됩니다) PHP 세션의 가비지 컬렉터가 기본적으로 비활성화되어 있습니다.
php.ini의 해당 설정은 session.gc_probability = 0이며, 0보다 큰 값으로 설정하면 가비지 컬렉터가 활성화됩니다. PHP의 기본값은 1이므로, 각 PHP 스크립트 호출 시 가비지 컬렉터가 1/100의 확률로 호출됩니다.
Debian 시스템에서는 세션 저장을 위한 기본 경로가 웹 서버 프로세스에 대해 쓰기 가능하지 않기 때문에 이 설정이 비활성화되어 있습니다(그리고 그렇게 되어서는 안 됩니다). 구식 세션 파일의 삭제는 여기서 시스템 크론 작업에 의해 수행됩니다.
php.ini의 발췌 내용:
; This is disabled in the Debian packages, due to the strict permissions
; on /var/lib/php5. Instead of setting this here, see the cronjob at
; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below.
; php scripts using their own session.save_path should make sure garbage
; collection is enabled by setting session.gc_probability
;session.gc_probability = 0이 설정은 기본 PHP 세션 처리(파일)를 사용하는 스크립트에는 괜찮지만, session_save_handler()를 사용하여 세션 읽기 및 쓰기를 위한 자체 루틴을 정의하는 사용자 정의 세션 처리를 사용할 때 문제를 일으킬 수 있습니다. 이러한 세션 관리 클래스는 대부분의 경우 가비지 컬렉터에 대한 자체 함수를 제공합니다.
문제는, 이 가비지 컬렉터 함수가 위에서 언급한 php.ini 설정을 가진 Debian 시스템에서는 절대 호출되지 않는다는 것입니다. 이는 세션 데이터가 MEMORY 유형의 MySQL 데이터베이스에 저장될 때 매우 중요합니다. 이 테이블은 MySQL 구성 값 max_heap_table_size에 의해 크기가 제한됩니다. 이 크기에 도달하면 모든 추가 세션 쓰기가 실패하고, 그로 인해 웹사이트가 제대로 작동하지 않을 수 있습니다.
이 사실을 알고 있으면, 자신의 세션 관리 클래스에서 가비지 수집을 위한 php.ini 설정을 덮어쓰는 것이 정말 중요합니다. 나는 실제 쓰기/읽기 없이 세션 관리 클래스의 작은 예제로 이를 보여줄 것입니다:
class session {
function __destruct() {
session_write_close();
}
function __construct() {
@ini_set("session.use_trans_sid","0");
@ini_set('session.gc_probability', 1); // Debian에서는 기본적으로 비활성화되어 있습니다...
// 사용자 정의 세션 핸들러 함수 활성화
session_set_save_handler(array(&$this,"_sess_open"),
array(&$this,"_sess_close"),
array(&$this,"_sess_read"),
array(&$this,"_sess_write"),
array(&$this,"_sess_destroy"),
array(&$this,"_sess_gc"));
@session_start();
}
// 사용자 정의 세션 핸들러 함수 선언
function _sess_open($sSavePath, $sSessionName) {
return true;
}
function _sess_close() {
return true;
}
function _sess_read($sKey) {
// 값 읽고 반환
}
function _sess_write($sKey, $val) {
// 새 값 쓰기
}
function _sess_destroy($sKey) {
// 세션 삭제
}
function _sess_gc($iMaxLifeTime) {
// 오래된 세션 삭제 (DB에서)
}
}
$mySession = new session();중요한 점은 생성자 내부에서 @ini_set(‘session.gc_probability’, 1)을 호출하는 것입니다. 그 후에는 세션 가비지 수집이 예상대로 작동해야 하며, Debian 시스템에서도 사용자 정의 세션 관리 클래스에서 작동해야 합니다.
새 게시물을 받은 편지함에서 받기
스팸은 없습니다. 언제든지 구독 해지 가능합니다.