Menu
Coddy logo textTech

__serialize 및 __unserialize

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 49번째.

객체를 저장이나 전송을 위해 문자열로 변환해야 할 때, PHP는 직렬화(serialization)를 사용합니다. __serialize()__unserialize() 매직 메서드를 사용하면 어떤 데이터가 저장되고 어떻게 복원되는지를 정확하게 제어할 수 있습니다.

__serialize() 메서드는 직렬화할 데이터 배열을 반환하며, __unserialize()는 해당 배열을 받아 객체를 다시 생성합니다:

<?php
class Session {
    public function __construct(
        private string $userId,
        private array $data,
        private int $createdAt
    ) {}
    
    public function __serialize(): array {
        return [
            'userId' => $this->userId,
            'data' => $this->data
        ];
    }
    
    public function __unserialize(array $data): void {
        $this->userId = $data['userId'];
        $this->data = $data['data'];
        $this->createdAt = time();
    }
    
    public function getCreatedAt(): int {
        return $this->createdAt;
    }
}

$session = new Session("user123", ["theme" => "dark"], time());
$serialized = serialize($session);

$restored = unserialize($serialized);
echo "User: " . $restored->getCreatedAt();

createdAt이 직렬화에서 제외되고 역직렬화될 때 새로운 타임스탬프를 받는 방식에 주목하세요. 이는 민감한 데이터, 임시 값 또는 데이터베이스 연결과 같이 직렬화할 수 없는 리소스를 제외하는 데 유용합니다.

이 메서드들은 PHP 7.4에서 기존의 __sleep()__wakeup() 메서드를 대체하여, 속성 이름 대신 데이터 배열을 직접 다루는 더 깔끔한 접근 방식을 제공합니다.

challenge icon

챌린지

쉬움

__serialize()__unserialize()가 저장되는 데이터와 복원 방법을 어떻게 제어하는지 보여주는 사용자 프로필 캐싱 시스템을 구축해 보겠습니다.

코드는 두 개의 파일로 구성됩니다:

  • UserProfile.php — 캐싱 기능이 있는 사용자 프로필을 나타내는 UserProfile 클래스를 생성합니다. 생성자 프로모션(constructor promotion)을 사용하여 $userId (string), $username (string), $email (string), $accessToken (string)에 대한 private 속성을 정의합니다. 프로필이 캐시된 시점을 저장하는 private $cachedAt 속성을 추가합니다(생성자에서 처음에 "not cached"로 설정). 클래스에는 다음이 필요합니다:
    • __serialize()userId, username, email만 포함된 배열을 반환합니다. accessToken은 민감한 정보이므로 절대 직렬화해서는 안 됩니다. cachedAt 타임스탬프는 복원 시 다시 생성됩니다.
    • __unserialize() — 데이터 배열에서 userId, username, email을 복원합니다. accessToken"expired"로 설정합니다(토큰은 유지되어서는 안 되기 때문입니다).
    • getInfo()"[username] ([email]) - Token: [accessToken] - Cached: [cachedAt]" 형식의 문자열을 반환합니다.
  • main.php — UserProfile 파일을 포함합니다. 사용자 ID, 사용자 이름, 이메일, 액세스 토큰의 네 가지 입력을 받습니다. 이 값들로 UserProfile 인스턴스를 생성합니다. 다음 세 줄을 출력합니다:
    • 원본 프로필 정보 (직렬화 전)
    • serialize()를 사용하여 프로필을 직렬화한 다음, unserialize()를 사용하여 복원된 프로필을 생성합니다. 복원된 프로필의 정보를 출력합니다.
    • 복원된 프로필의 토큰이 원본과 일치하는지 여부에 따라 "Token preserved: yes" 또는 "Token preserved: no"를 출력합니다 (힌트: 복원 시 토큰이 만료되므로 일치하지 않아야 합니다).

이 패턴은 사용자 데이터를 안전하게 캐싱하는 데 필수적입니다. 프로필 정보는 저장하고 싶지만 액세스 토큰과 같은 민감한 자격 증명은 절대 유지하고 싶지 않을 때 사용합니다. 캐시에서 프로필을 복원하면 토큰이 만료된 것으로 표시되어 애플리케이션이 새 토큰을 얻도록 강제합니다.

치트 시트

__serialize()__unserialize() 매직 메서드는 직렬화 중에 저장되는 데이터와 객체가 복원되는 방식을 제어합니다.

__serialize()는 직렬화할 데이터 배열을 반환합니다:

<?php
public function __serialize(): array {
    return [
        'userId' => $this->userId,
        'data' => $this->data
    ];
}

__unserialize()는 배열을 전달받아 객체를 다시 빌드합니다:

<?php
public function __unserialize(array $data): void {
    $this->userId = $data['userId'];
    $this->data = $data['data'];
    $this->createdAt = time();
}

객체를 문자열로 변환하려면 serialize()를 사용하고, 이를 복원하려면 unserialize()를 사용합니다:

<?php
$serialized = serialize($session);
$restored = unserialize($serialized);

이 메서드들은 민감한 데이터, 임시 값 또는 직렬화할 수 없는 리소스(예: 데이터베이스 연결)를 제외하는 데 유용합니다. 속성은 역직렬화 중에 새로운 값으로 다시 생성될 수 있습니다.

직접 해보기

<?php

require_once 'UserProfile.php';

// 입력 읽기
$userId = trim(fgets(STDIN));
$username = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$accessToken = trim(fgets(STDIN));

// TODO: 입력된 값으로 UserProfile 인스턴스 생성

// TODO: 원본 프로필 정보 출력 (직렬화 전)

// TODO: 프로필을 직렬화한 후, 다시 역직렬화하여 복구된 프로필 생성

// TODO: 복구된 프로필 정보 출력

// TODO: 복구된 프로필의 토큰이 원본과 일치하는지 여부에 따라
// "Token preserved: yes" 또는 "Token preserved: no" 출력

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨