데비안(및 우분투)에서 사용자 정의 세션 관리를 사용할 때 PHP 세션 데이터가 삭제되지 않습니다.

데비안(및 우분투)에서 사용자 정의 세션 관리를 사용할 때 PHP 세션 데이터가 삭제되지 않습니다.

2022-10-19 last update

5 minutes reading apache php
데비안 시스템에서 (내가 아는 한 이것이 우분투에도 적용됨) PHP 세션에 대한 가비지 수집기는 기본적으로 비활성화되어 있습니다.
php.ini의 해당 설정은 session.gc_probability = 0이며 0보다 큰 값으로 설정하면 가비지 수집기를 활성화합니다. PHP의 기본값은 1이므로 가비지 수집기는 각 PHP 스크립트 호출에서 1/100의 확률로 호출됩니다.

데비안 시스템에서 이 설정은 세션 저장소의 기본 경로가 웹 서버 프로세스에 대해 쓸 수 없다는 사실 때문에 비활성화되어 있습니다. 오래된 세션 파일 삭제는 여기에서 시스템 cron 작업에 의해 수행됩니다.
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 설정으로 데비안 시스템에서 호출되지 않는다는 것입니다. 이것은 세션 데이터가 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); // in debian this is disabled by default...
         
        // enable customized session handler functions
        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();
    }
 
    // declare user defined session handler functions
    function _sess_open($sSavePath, $sSessionName) {
        return true;
    }
     
    function _sess_close() {
        return true;
    }
     
    function _sess_read($sKey) {
        // read and return value
    }
     
    function _sess_write($sKey, $val) {
        // write new value
    }
     
    function _sess_destroy($sKey) {
        // destroy session
    }
     
    function _sess_gc($iMaxLifeTime) {
        // delete old sessions (from db)
    } 
}
 
$mySession = new session();
중요한 것은 생성자 내부에서 @ini_set('session.gc_probability', 1)을 호출하는 것입니다. 이 후에는 세션 관리 클래스가 있는 데비안 시스템에서도 세션 가비지 수집이 예상대로 작동해야 합니다.