__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() 메서드를 대체하여, 속성 이름 대신 데이터 배열을 직접 다루는 더 깔끔한 접근 방식을 제공합니다.
챌린지
쉬움__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" 출력
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8매직 메서드
매직 메서드 소개__toString 및 __debugInfo__get, __set, __isset, __unset__call 및 __callStatic__clone 및 객체 복제__serialize 및 __unserialize요약 - 커스텀 컬렉션