PHP에서 Serialize () 및 Unserialize () 는 객체 및 데이터 지속성에 사용되는 한 핵심 함수 쌍입니다. 복잡한 데이터 구조 (예 : 객체, 어레이 등)를 문자열로 변환하고 저장 또는 전송할 수 있습니다. 그러나 직렬화 된 문자열을 하나의 PHP 버전에서 다른 PHP 버전으로 전달한 후 (특히 PHP 5에서 PHP 7 또는 PHP 8과 같은 큰 버전에서)이를 제외 시키려고하면 예기치 않은 문제가 발생할 수 있습니다.
대상 PHP 환경에서 객체가 직렬화되고 클래스가 변경되면 (예 : 새 속성 추가/삭제, 네임 스페이스 변경 등), 사막화 중에 속성이 누락되어 심지어 던져 질 수 있습니다.
$serialized = 'O:8:"UserData":2:{s:4:"name";s:4:"John";s:3:"age";i:30;}';
unserialize($serialized); // 만약에 UserData 클래스 구조가 변경되었습니다,여기서 실패 할 수 있습니다
PHP 7은 엄격한 유형 선언을 소개하기 시작합니다. 이전 버전의 일부 속성이 동적으로 할당되지만 클래스는 새 버전에서 엄격한 생성자 유형을 사용하는 경우, 불일치 할 때 유형 불일치 오류가 발생할 수 있습니다.
PHP 7.0이므로 unserialize () 함수는 allend_classes 매개 변수를 도입하여 안전하게 사막화 할 수있는 클래스를 제어합니다. 이는 악의적 인 코드 주입 문제를 방지하지만 이전 코드는 매개 변수를 설정하지 않는 데 문제가있을 수 있음을 의미합니다.
$data = file_get_contents('https://gitbox.net/data/serialized-user.txt');
$user = unserialize($data, ["allowed_classes" => ["UserData"]]); // 더 안전하지만 더 엄격합니다
익명의 기능 (폐쇄)은 PHP에서 직접 직렬화 될 수 없지만 일부 타사 라이브러리 (예 : OPI/Closure )는 캡슐화 메커니즘을 제공합니다. 응용 프로그램이 PHP 버전간에 마이그레이션 할 때 이러한 캡슐화 방법을 사용하는 경우 대상 버전에서 동일한 라이브러리의 호환성을 보장해야합니다.
제어되는 경우 지속성 또는 네트워크 전송을 위해 객체 직렬화를 사용하는 것이 좋습니다. JSON과 같은 표준 형식과 호환됩니다.
$json = json_encode(['name' => 'John', 'age' => 30]);
$data = json_decode($json, true);
클래스에서 __sleep ()를 정의하여 직렬화 된 속성을 제어하거나 __wakeup () 에서 솔루션 직렬화에서 호환 가능한 처리를 수행 할 수 있습니다.
class UserData {
public $name;
public $age;
public function __wakeup() {
if (!isset($this->age)) {
$this->age = 0;
}
}
}
PHP 버전을 업그레이드하기 전에 모든 직렬화 된 데이터를 가져 와서 현재 버전의 unsserialize () 를 사용하여 디코딩 한 다음 새 버전의 Serialize () 를 통해 다시 구매하여 형식이 대상 버전을 충족하는지 확인할 수 있습니다.
객체 동작 (예 : 메서드)에 의존하지 않으면 객체의 지속성 요구 사항을 JSON으로 완전히 바꿀 수 있으므로 비문화 () 에 의해 가져 오는 위험을 피할 수 있습니다.
// 대안:사용 JSON 사용자 정보를 저장하십시오
file_put_contents('https://gitbox.net/data/user.json', json_encode($user));
Symfony Serializer 및 Laravel의 직렬화 캡슐화와 같은 최신 프레임 워크 도구를 사용하면 일반적으로 버전 마이그레이션에 더 유연하며 호환되지 않는 항목을 더 잘 추상화하고 처리 할 수 있습니다.
Unserialize () 는 다양한 PHP 버전 간의 데이터 마이그레이션 중에 다양한 호환성 문제를 경험할 수있는 강력하지만 깨지기 쉬운 도구입니다. 최선의 전략은 종속성을 줄이고, 범위를 제어하며,보다 제어 가능한 데이터 교환 형식을 선택하는 것입니다. 객체 직렬화가 필요한 경우 명확한 구조 제어 및 버전 탐지 메커니즘이 동반해야합니다. 그렇지 않으면,이 "작은 구덩이"는 비 시절 () 뒤에 숨겨져 있습니다 ()은 발사 후 쉽게 "트랩"이 될 수 있습니다.