我有一个应用程序,用户可以在其中将序列化的 PHP 对象保存在数据库中。 假设这是一个简单的游戏。 问题是:如果我更新了这个游戏并且用户会尝试加载他的存档怎么办? 假设我有一个这样的课程:
class Car {
private Engine $engine;
private array $wheels;
private Color $color;
private int $id;
// methods ommitted, as they donesn't matter
}
假设某个用户创建了新车辆并保存在他的帐户中(作为数据库中的序列化文本)。 一段时间后,我决定重建这个类: 假设我将 $id 属性的名称更改为 $number,删除了 $wheels 属性,将 $engine 属性更改为 public 并添加了 $fuel 属性:
class Car {
public Engine $engine;
private Color $color;
private int $number;
private float $fuel;
}
如果用户现在尝试加载他的保存,unserialize() 函数将不起作用。
问题是:
如何解决?哪种方法最好?我应该在每次更新期间重建数据库中所有保存的数据吗?我应该在我的类中实现一些 __wakeup() 或 unserialize() 方法吗?怎么做?有没有好的方法/最佳实践/模式设计来解决这个问题?
// 更新: 好的,我找到了一些解决方案。我不知道这是否是一个好习惯,但它(几乎)有效: 在新的 Car 类中,我实现了一个 __wakeup() 方法,如下所示:
public function __wakeup() {
unset($this->wheels);
$this->number = $this->id;
unset($this->id);
}
如您所见,第一行取消了 $wheels 的设置,因为该属性不再存在,接下来的两行将 $id 更改为 $number。 但是,这一行:
$this->number = $this->id;
产生错误:
Undefined property: Car::$id in ...
但是我可以在调试器和 var_dump 中看到这个变量的值:
object(Car)[1]
public string 'color' => string 'yellow' (length=6)
private string 'engine' => string 'V4' (length=2)
private int 'number' => *uninitialized*
private float 'fuel' => float 50
private 'wheels' =>
array (size=4)
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 => string 'c' (length=1)
3 => string 'd' (length=1)
private 'id' => int 88
所以 id 存储在内存中的某个地方,但我不知道如何访问它。有什么想法吗?