読者です 読者をやめる 読者になる 読者になる

serializeしたオブジェクトの継承元が変わったらunserializeできるのか?

PHP

疑問点。PHPにおいてオブジェクトをserializeし、その後そのオブジェクトの継承関係が変わったら、正しくunserializeできるのか?

検証コード。親クラスなしのDogというクラスのインスタンスをserializeしたファイルに書きだした後、Dog < SocialDog < BaseDog という継承関係に変更に変更したコードで読みだす。

<?php
// dog.php

class Dog {
	protected $name;

	public function setName($name) {
		$this->name = $name;
	}

	public function getName() {
		return $this->name;
	}
}

function main() {
	$dog = new Dog();
	$dog->setName('Zynga');

	file_put_contents('zynga.dat', serialize($dog));
}

main();

実行すると以下のようにzynga.datが書き出された。

$ php dog.php
$ cat zynga.dat
O:3:"Dog":1:{s:7:"*name";s:5:"Zynga";}

以下のコードで継承関係を変えて、シリアライズしたデータからDogクラスをunserializeする。

<?php
// dog2.php

class BaseDog {
	public function isSocial() {
		return false;
	}
}

class SocialDog {
	public function isSocial() {
		return true;
	}
}

class Dog extends SocialDog {
	protected $name;

	public function setName($name) {
		$this->name = $name;
	}

	public function getName() {
		return $this->name;
	}
}

function main() {
	$data = file_get_contents('zynga.dat');
	$dog = unserialize($data);

	if ($dog->isSocial()) {
		printf("%s is a social dog!\n", $dog->getName());
	} else {
		printf("%s isn't a social dog...\n", $dog->getName());
	}
}

main();

結果。

% php dog2.php 
Zynga is a social dog!

結論としては、「できる」らしい。