我将某些对象存储在数据库中。数据库中的每个节点都带有一个序列化对象。节点可以有子节点,因此对象也可以有子节点。因此,我希望用包含其直接子级的数组填充对象中的$children属性。当对象未序列化时,应该填充$children。
在试图避免从外部做这件事时,我想我宁愿让对象自己去做。但是,对象不知道它属于哪个数据库条目。因此,当调用__wakeup()时,对象缺少加载自己的相应数据库条目所需的信息。
看起来最好的是能够将一个变量传递给__wakeup(),尽管我知道unserialize()没有提供这样的选项。
我没能找到任何有关这方面的资料。我即将得出结论,这是不可能的,除了使用全局,这不是我会选择的路线。
有可能吗?如果是,怎么做?
发布于 2014-03-23 09:57:03
神奇的方法不允许传递参数。。这里的想法是拥有对象所需的一切,以便在序列化形式中将自己非序列化为有效状态,例如,当对象被序列化时,它期望对象处于有效状态。
这意味着,如果子数据库条目所属的信息丢失,但对象必须处于有效状态,则首先应该将其添加到对象中。然后,在取消对象序列化时,可以简单地访问该值。这将是最干净的解决方案。
另一种选择是诉诸全球。我同意,没人想那样。
还有一个同样令人怀疑和不可思议的选项是,在取消对象序列化以添加缺少的信息之前,先处理序列化的表单。
这里有一个概念的证明:
function unserialize_with_args($string, array $args, $key = 'tmp')
{
// serialize $args to $key for inserting into $string
$tmps = sprintf(
's:%d:"%s";%s}',
strlen($key),
$key,
serialize($args)
);
// increase property count in original string
$string = preg_replace_callback(
'/^(O:\d+:"[a-z]+":)(\d+)/i',
function (array $matches) {
return $matches[1] . ($matches[2] + 1);
},
$string
);
// insert $tmps, unserialize, remove tmps
$instance = unserialize(substr_replace($string, $tmps, -1));
unset($instance->$key);
return $instance;
}这样你就能做到:
class Foo
{
public function __wakeup()
{
print_r($this->tmp);
}
}
unserialize_with_args(
serialize(new Foo),
[1,2,3]
);运行该代码将打印(演示):
Array
(
[0] => 1
[1] => 2
[2] => 3
)这是因为函数将属性tmp添加到序列化表单中,以保存作为$args传递的序列化数组。因此,当对象被唤醒时,它将有权访问这些值。函数将在返回未序列化的对象之前删除该属性,因此只能在__wakeup期间访问该属性。
但是,为了明确这个解决方案:,这是绝望的措施,。首先,尝试以序列化形式提供缺少的信息。
https://stackoverflow.com/questions/22588446
复制相似问题