인프런 커뮤니티 질문&답변

Henu님의 프로필 이미지
Henu

작성한 질문수

PHP 7+ 프로그래밍: 객체지향

27 - 세션 (Sessions)

Session을 생성할 때 sessions 테이블 id 컬럼의 값이 어떻게 결정되는지 궁금합니다.

해결된 질문

작성

·

529

2

안녕하세요, Sessions 강의를 듣고 궁궁한 것이 생겨 질문드립니다.

 

강의 내용에서는 SessionHandlerInterface의 구현체 클래스를 선언하여 사용하는 것으로 보이는데요.

 

index.php의 예제 코드 실행시 처음 생성되는 SESSION 데이터가 있으면 sessions 테이블에 세션 정보가 INSERT 되는 것으로 확인이 되었습니다.

 

하지만 sessions 테이블의 id 컬럼의 값이 자동으로 들어가지는 것을 확인할 수 있었는데요. 이 id은 PHPSESSID에서 가져오는 것 같은데, 그 과정에 대해 알 수 있을까요?

 

답변 2

2

정상우님의 프로필 이미지
정상우
지식공유자

음 간단히 요약을 해보도록 하죠.

세션을 처음 생성할 때

  1. session_start() 를 실행하면 내부적으로 새로운 Session ID 를 생성하고 SessionHandlerInterface::read() 에 $id 값을 넘깁니다.
  2. $id 를 사용하여 해당 이름을 가진 파일을 읽거나, 또는 해당 키를 가진 데이터베이스 레코드를 조회하여 세션 데이터를 반환합니다. 만약 넘겨받은 $id 를 기반으로 파일이나 데이터베이스 레코드가 존재하지 않는다면 새로 생성하는 과정이 필요할 수도 있습니다.
  3. 세션을 처음 생성한다면 생성된 Session ID 를 가진 PHPSESSID 쿠키를 브라우저에 저장하도록 지시합니다.

세션 쿠키가 존재할 때

  1. 브라우저에 PHPSESSID 쿠키가 존재한다면 요청시 쿠키값을 포함합니다.
  2.  session_start() 를 실행하면 브라우저에서 보내준 PHPSESSID 값을 조회하여 파일 또는 데이터베이스에서 세션을 읽으려고 시도합니다. SessionHandlerInterface::read() 가 호출되며 PHPSESSID 에 저장된 $id 값을 넘겨받습니다.

공통적으로, $_SESSION 에 값을 쓰려고하면 SessionHandlerInterface::write() 에서 넘겨받은 $id, $data 를 기반으로 세션에 데이터를 씁니다.

FlieSessionHanlder

이해를 돕고자 FlieSessionHanlder 를 생성했습니다.

class FileSessionHanlder implements SessionHandlerInterface
{
    /**
     * @var string $path 세션 저장 경로
     */
    protected $path = './sessions';

    /**
     * 새로운 세션이 들어오거나 이미 있는 세션을 조회
     * 
     * @param string $key 세션이 없을 때 내부적으로 자동 생성됩니다. 만약, PHPSESSID 가 존재하는 경우 그 값으로 대체합니다.
     */
    public function read($key)
    {
        // 새로운 세션일 때는 파일이 존재하지 않습니다. 그래서 에러를 유발하지만 @ 연산자로 무시합니다.
        // 이 경우에는 생성을 SessionHandlerInterface::write() 에서 합니다.
        return (string) @file_get_contents($this->path . '/' . $key);
    }

    /** 
     * 세션에 데이터 쓰기
     */
    public function write($key, $val)
    {
        // file_put_contests 는 파일이 존재하지 않을 경우 생성.
        // 존재하는 경우 덮어쓰기
        return file_put_contents($this->path . '/' . $key, $val) === false ? false : true;
    }

    public function destroy($key) { return true; }
    public function close() { return true; }
    public function gc($maxlifetime) { return true; }
    public function open($save_path, $session_name) { return true; }
}

session_set_save_handler(new FileSessionHanlder());

session_start(); // SessionHandlerInterface::read()

$_SESSION['message'] = "Hello, world"; // SessionHandlerInterface::write()
var_dump($_SESSION['message']); // Hello, world
Henu님의 프로필 이미지
Henu
질문자

너무나도 감사합니다!

이번 댓글로 이해가 한방에 되었네요.

최고입니다!

2

정상우님의 프로필 이미지
정상우
지식공유자

안녕하세요. 이 부분에서 대해서는 기대하는 답변이 아닐 수도 있습니다. 세션 ID 는 PHP 에서 내부적으로 해시함수(Hash Functions) 를 사용하여 ID 를 자동으로 생성합니다. 자동 생성된 ID 를 키로 하는 파일 또는 데이터베이스 레코드에 입력됩니다. 세션 쿠키는 ID 값을 그저 가지고만 있을 뿐이고 서버에서 파일 또는 데이터베이스에 저장된 세션을 찾기 위한 용도로 사용 될 뿐입니다.

이 내용은 여기서 설명하는 것보다 제 블로그에 쓴 글을 참고하는 것이 도움이 될 수 있습니다.

PHP: 쿠키와 세션
쿠키(Cookie)와 세션(Session)에 대해 알아보자 (feat. Golang)

Henu님의 프로필 이미지
Henu
질문자

답변 감사합니다.

'세션 ID 는 PHP 에서 내부적으로 해시함수(Hash Functions) 를 사용하여 ID 를 자동으로 생성'에 대한 내용은 이해를 했습니다.

다만, 강의 내용에서 SessionHandlerInterface의 구현체인 DatabaseSessionHandler 클래스에서 read($id), write($id, $payload) 메소드의 $id 파라미터에 값이 바인딩되는지 궁금합니다.

'자동 생성된 ID 를 키로 하는 파일 또는 데이터베이스 레코드에 입력됩니다. '에서 유추해 보건데,

session_set_save_handler(new DatabaseSessionHandler())를 통해 세션 관리는 데이터베이스를 사용하겠다라고 명시하였으니, PHP 내부적으로 session_start() 시 PHPSESSID 쿠키 값을 가져와 자동으로 바인딩 되는게 맞을까요?

Henu님의 프로필 이미지
Henu

작성한 질문수

질문하기