PHP: 如何防止序列化命中某个成员
PHP: How to prevent serialize from hitting a certain member
我有一个用户对象,其受保护的成员指向一个 PDO 对象。
我正在使用 Silex/Symfony,当我尝试登录时 Symfony\Component\Security\Core\Authentication\Token\AbstractToken
开始序列化该对象并给出异常,因为 PDO 对象无法序列化。
我尝试将成员设为私有,但这没有帮助。如果我取消设置 __sleep 中的 属性 我不确定如何将它放回 __wakeup 中,因为该成员是通过在构造函数中传递来设置的。
我见过的示例通过静态查找取回不可序列化的内容,但我正在努力避免这种情况。有什么想法吗?
您需要对您的用户对象实施 Serializable
。
class User implements UserInterface, Serializable
{
// ...
public function serialize()
{
// see http://php.net/manual/en/serializable.serialize.php
return serialize(array(
$this->id,
$this->username,
$this->password
));
}
public function unserialize($serialized)
{
// see http://php.net/manual/en/serializable.unserialize.php
list ($this->id, $this->username, $this->password) = unserialize($serialized);
}
}
编辑
警告:此答案仅针对问题“如何防止序列化命中某个成员”。如果你发现自己有类似的问题,那么你应该重新考虑你在做什么。详情请看@Bryan Agee 的回答。
听起来你的模型对象中有持久化逻辑,这是你问题的真正根源;您可能想看看存储库设计模式来解决这个问题。
与此同时,重新填充该 PDO 对象的唯一真正选择是使用邪恶的全局变量;你的 __wakeup() 必须伸手去拿一个实例。
我想你也可以覆盖加载用户的服务,并将其替换为在反序列化后立即注入数据库的服务,但这似乎有点毛茸茸——最好只是从模型中提取持久性代码,并且只序列化模型。
一个小的补充:JMS Serializer 是一个很酷的 symfony 包,它允许你在你的实体中做注释,精确地选择你想要序列化(或不序列化)的 property/method。
我有一个用户对象,其受保护的成员指向一个 PDO 对象。
我正在使用 Silex/Symfony,当我尝试登录时 Symfony\Component\Security\Core\Authentication\Token\AbstractToken
开始序列化该对象并给出异常,因为 PDO 对象无法序列化。
我尝试将成员设为私有,但这没有帮助。如果我取消设置 __sleep 中的 属性 我不确定如何将它放回 __wakeup 中,因为该成员是通过在构造函数中传递来设置的。
我见过的示例通过静态查找取回不可序列化的内容,但我正在努力避免这种情况。有什么想法吗?
您需要对您的用户对象实施 Serializable
。
class User implements UserInterface, Serializable
{
// ...
public function serialize()
{
// see http://php.net/manual/en/serializable.serialize.php
return serialize(array(
$this->id,
$this->username,
$this->password
));
}
public function unserialize($serialized)
{
// see http://php.net/manual/en/serializable.unserialize.php
list ($this->id, $this->username, $this->password) = unserialize($serialized);
}
}
编辑
警告:此答案仅针对问题“如何防止序列化命中某个成员”。如果你发现自己有类似的问题,那么你应该重新考虑你在做什么。详情请看@Bryan Agee 的回答。
听起来你的模型对象中有持久化逻辑,这是你问题的真正根源;您可能想看看存储库设计模式来解决这个问题。
与此同时,重新填充该 PDO 对象的唯一真正选择是使用邪恶的全局变量;你的 __wakeup() 必须伸手去拿一个实例。
我想你也可以覆盖加载用户的服务,并将其替换为在反序列化后立即注入数据库的服务,但这似乎有点毛茸茸——最好只是从模型中提取持久性代码,并且只序列化模型。
一个小的补充:JMS Serializer 是一个很酷的 symfony 包,它允许你在你的实体中做注释,精确地选择你想要序列化(或不序列化)的 property/method。