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