동시, 분산 또는 장기 실행되는 PHP 응용 프로그램을 구축 할 때 기존 파일 시스템 세션 저장 방법은 세션 스팸 데이터 축적으로 이어져 성능 및 안정성에 영향을 줄 수 있습니다. 이 문제를 해결하기 위해 PHP는 SessionHandlerInterface 인터페이스를 제공하여 개발자가 세션 스토리지 로직을 사용자 정의 할 수 있습니다. 여기서 GC () 메소드는 쓰레기 청소 프로세스를 제어하는 핵심입니다.
SessionHandlerInterface :: GC는 이 인터페이스에 의해 정의 된 메소드입니다. 수비 수집 작업을 수행하기 위해 세션 데이터가 PHP 내에서 만료되었다고 판단 될 때 그 기능이 호출됩니다. 메소드 서명은 다음과 같습니다.
public function gc(int $max_lifetime): int|false;
$ max_lifetime : 세션의 최대 생존 시간 (단위 : 초)을 나타냅니다.
반환 값 : 청소 세션 수를 반환하거나 성공시 True를 반환하고 실패시 허위를 반환합니다.
사용자가 세션 프로세서 (Custom Session Handler)를 사용자 정의하고 인터페이스를 구현하면 구식 세션 데이터를 청소하는 정책 이이 메소드에서 정의 될 수 있습니다.
PHP는 기본적으로 파일 기반 세션 스토리지를 사용하며 GC 메커니즘은 확률 트리거 ( Session.gc_probability 및 Session.gc_divisor )를 기반으로합니다. 이는 요청할 때마다 청소 로직을 실행하지 않음을 의미합니다.
예를 들어:
session.gc_probability = 1
session.gc_divisor = 1000
쓰레기 청소는 1/1000의 확률로 트리거되었음을 나타냅니다. 이 전략은 교통량이 적은 시스템에서 만료 된 세션 축적을 유발할 수 있으며, 이는 교통량이 많은 시스템에서 자주 발생하여 성능에 영향을 줄 수 있습니다.
아래는 데이터베이스 스토리지를 기반으로하는 사용자 정의 세션 핸들러 예제이며 GC () 메소드를 최적화하여 성능을 향상시키는 방법을 보여줍니다.
class DbSessionHandler implements SessionHandlerInterface {
protected $db;
public function __construct(PDO $db) {
$this->db = $db;
}
public function open($savePath, $sessionName): bool {
return true;
}
public function close(): bool {
return true;
}
public function read($id): string|false {
$stmt = $this->db->prepare("SELECT data FROM sessions WHERE id = :id AND expires > :now");
$stmt->execute([':id' => $id, ':now' => time()]);
return (string) $stmt->fetchColumn();
}
public function write($id, $data): bool {
$expires = time() + (int)ini_get("session.gc_maxlifetime");
$stmt = $this->db->prepare("
REPLACE INTO sessions (id, data, expires) VALUES (:id, :data, :expires)
");
return $stmt->execute([
':id' => $id,
':data' => $data,
':expires' => $expires,
]);
}
public function destroy($id): bool {
$stmt = $this->db->prepare("DELETE FROM sessions WHERE id = :id");
return $stmt->execute([':id' => $id]);
}
public function gc($max_lifetime): int|false {
$stmt = $this->db->prepare("DELETE FROM sessions WHERE expires < :time");
$stmt->execute([':time' => time()]);
return $stmt->rowCount();
}
}
위의 구현에서 GC () 메소드는 데이터베이스에서 만료 된 모든 세션 레코드를 명시 적으로 삭제합니다. 기본 확률 기반 GC와 비교 하여이 방법은 더 신뢰할 수 있으며 시스템 타이밍 작업 (예 : CRON)과 함께 사용하여 정기적 인 청소를 달성 할 수 있습니다.
사용자 정의 프로세서를 정의한 후에는 다음과 같은 방법으로 활성화 할 수 있습니다.
$handler = new DbSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();
데이터베이스 정리 스크립트 또는 작업 스케줄러를 사용하는 경우 SESSION.GC_PROBALIATION을 0으로 설정하여 자동 GC를 완전히 끕니다.
session.gc_probability = 0
그런 다음 계획된 작업에서 주기적으로 실행하십시오.
$handler->gc(1440); // 예를 들어, 각각24몇 분 안에 한 번 정리하십시오
데이터베이스 외에도 세션 스토리지 및 GC 메커니즘은 Redis, Memcached 등을 기반으로 구축 할 수 있습니다. 예를 들어, Redis를 사용하는 경우 복잡한 GC () 메소드를 수동으로 구현하지 않고 TTL 메커니즘으로 자동 만료 될 수 있습니다.
$redis->setex("sess_$id", $max_lifetime, $data);
더 많은 예는 https://m66.net/examples/session handler 를 참조하십시오.
PHP 개발자는 SessionHandlerInterface :: GC () 메소드를 구현함으로써 세션 쓰레기 청소를 완전히 제어 할 수 있으며, 이는 고성능의 확장 가능한 웹 애플리케이션을 구축하는 데 중요합니다. 데이터베이스, REDIS 또는 기타 미들웨어를 사용하든 GC () 및 시스템 수준 스케줄링 도구의 합리적 사용에 관계없이 세션 관리 효율성 및 시스템 유지 관리 가능성을 크게 향상시킬 수 있습니다.
관련 태그:
SessionHandlerInterface