在PHP序列化之前更改对象

时间:2013-07-04 10:11:11

标签: php serialization reflection

我有以下类树:

class A /* Base class */
{ 
  private/protected/public $state 
} 

class B extends A /* Auto generated class, not to be modified */
{
  private $v
  public function getV() { return $this->v; }
  public function setV($val) { $this->v = $val; }
}

class C extends B { /* Custom code */ }

只有一个A类。有多个类,如B类,所有这些类都有一个类似C的子类.B类自动生成,不应修改。

我在会话中存储类型为C的对象。我想要做的是在每个实例中存储一些状态信息,就在PHP被序列化之前,并且当它被反序列化时它将对它做一些事情。我希望所有这些都在A类中实现。

考虑到,我需要使用__sleep()Serializable接口。由于PHP手册所说的,使用__sleep是不可能的:

  

__sleep()无法返回父类中私有属性的名称。执行此操作将导致E_NOTICE级别错误。相反,您可以使用Serializable接口。

这意味着如果我睡眠了C类的实例,我将松开在B中声明的私有变量。所以我想使用Serializable,但由于某种原因,我根本无法让它做我想要的。

从本质上讲,我希望将对象序列化,就像我自己没有实现任何序列化内容一样,我只想在$state之前添加信息。我已尝试使用ReflectionObject->getProperties()覆盖所有数据,但我似乎无法找到正确的方法来获取和设置B类中的私有值以进行序列化和反序列化。

我该怎么做?

1 个答案:

答案 0 :(得分:2)

您可以使用Reflection类来完成此操作。您必须获取类本身及其每个父类的属性。获取和设置属性值可以使用ReflectionProperty的{​​{1}}和getValue方法,并结合setValue来访问私有和受保护的属性。结合这些,我想出了以下代码:

setAccessible

这似乎做你想要的。