当然,有许多方法可以存储数据库。数据库是最明显的。但其他包括JSON,XML等。
我现在正在处理的项目的探测是存储的数据包含回调函数作为对象的一部分。据我所知,函数无法序列化。那么,我该怎么办?
将此数据存储为要包含的PHP文件是否可以接受?如果是这样,我应该创建一个包含所有内容的大文件,还是将其分成数据库中每个“行”的单独文件?
有没有其他可能更好的选择?
答案 0 :(得分:1)
根据回调的详细程度,对于序列化,您可以将它们包含在使用某些__sleep
(创建回调表示)的类中。 __wakeup
(恢复回调)voodoo,使用__invoke()
方法调用实际的回调。假设你可以反向工程/重新创建那些回调(即指向的对象是明确的)....如果没有,你可能运气不好。
答案 1 :(得分:0)
存储回调的名称,具有从名称到函数的查找表,使用table.call(obj, name, ...)
或table.apply(obj, name, ...)
来调用。可序列化对象本身没有任何代码。由于它们是开发人员创建的,因此应该有一个有限的库存,它们应该是代码,不应该被序列化。
或者,制作一个实现回调的原型,并将其分配给obj.__proto__
。在序列化之前杀死obj.__proto__
- 所有功能都消失了。之后恢复它。不确定是否跨浏览器兼容;我似乎已经阅读了一些关于__proto__
无法在某些浏览器中访问的内容 khminternetexploreroperakhm
答案 2 :(得分:0)
如果它们是由开发人员创建的,那么应该很容易想出一种格式...例如使用JSON:
{
"callback" : {
"contextType": "instance", // or "static"
"callable" : "phpFunctionName",
"arguments" : []
}
}
然后在模型上可以使用此功能,您可以执行以下操作:
protected function invokeCallback($json, $context = null) {
$data = json_decode($json, true);
if(isset($data['callaback'])) {
if($data['contextType'] == 'instance') {
$context = is_object($context) ? $context : $this;
$callable = array($context, $data['callable']);
} else {
// data[callable] is already the string function name or a array('class', 'staticMethod')
$callable = $data['callable'];
}
if(is_callable($callable) {
return call_user_func_array($callable, $data['arguments'];
} else {
throw new Exception('Illegal callable');
}
}
return false;
}
还有一些错误处理需要在那里进行,以及对你想要允许的可调用的一些筛选,但你明白了。