当然,存储数据库的方法有很多种。数据库是其中最明显的。但其他包括 JSON、XML 等。
我现在正在处理的项目中的问题是存储的数据包括回调函数作为对象的一部分。据我所知,函数不能序列化。所以我该怎么做?
是否可以将此数据存储为要包含的 PHP 文件?如果是这样,我应该创建一个包含所有内容的大文件,还是将它分成数据库的每一“行”的单独文件?
有没有更好的选择?
根据您的回调的复杂程度,对于序列化,您可以将它们全部包装在一个类中,该类利用一些__sleep
(创建回调表示)和__wakeup
(恢复回调)voodoo,并使用__invoke()
调用实际回调的方法。假设您可以对这些回调进行逆向工程/重新创建(即明确指向的对象).... 如果没有,您可能不走运。
相反,存储回调的名称,有一个从名称到函数的查找表,使用table.call(obj, name, ...)
或table.apply(obj, name, ...)
调用。可序列化对象本身没有任何代码。由于它们是开发人员创建的,因此它们的库存应该是有限的,它们应该在代码中,并且不应该被序列化。
或者,制作一个实现回调的原型,并将其分配给obj.__proto__
. obj.__proto__
在序列化之前杀死- 所有功能都消失了。之后恢复它。不确定是否跨浏览器兼容;我似乎读过一些关于__proto__
在某些浏览器中无法访问的内容khminternetexploreroperakhm
好吧,如果它们是由开发人员创建的,那么应该很容易提出一种格式......例如使用 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;
}
还有一些需要在那里进行的错误处理以及对您想要允许的可调用对象的一些筛选,但您明白了。