提问人:mario 提问时间:10/3/2010 最后编辑:mario 更新时间:10/6/2010 访问量:268
方法链劫持
method chain hijacking
问:
这不是一个真正流畅的界面。我有一个对象,它构建了一个方法堆栈。它由单个函数调用执行。但现在我可能会添加另一个虚拟方法,它“接管”该方法堆栈。
用例:我正在将我的超全局变量包装到对象中。这允许我“强制”输入过滤。$_GET 和 CO 提供简单的消毒方法。我的新版本现在允许链接原子过滤器。例如:
$_GET->ascii->nocontrol->text["field"]
这是一个方法调用。它使用尖括号。但这是一个很好的技巧,可以简化重写 .无论如何。$_GET["field"]
现在偶尔也会有带有枚举字段的表单,如 field[0],field[1],field[2]。这就是我添加虚拟 ->array 过滤器方法的原因。它劫持收集到的方法堆栈,并迭代剩余的过滤器,例如 $_POST 数组值。例如。$_POST->array->int["list"]
略微缩短的实现:
function exec_chain ($data) {
...
while ($filtername = array_pop($this->__filter)) {
...
$data = $this->{"_$filtername"} ($data);
...
}
function _array($data) {
list($multiplex, $this->__filter) = array($this->__filter, array());
$data = (array) $data;
foreach (array_keys($data) as $i) {
$this->__filter = $multiplex;
$data[$i] = $this->exec_chain($data[$i]);
}
return $data;
}
方法堆栈在列表中组装。上面的 exec_chain() 只是遍历它,每次删除第一个方法名称。虚拟_array处理程序通常是第一种方法。它只是窃取该方法堆栈,并在每个数组元素上重新执行其余部分。与上面的示例代码不完全相同,但它只是重复重新填充原始方法堆栈。$this->__filter
它有效。但感觉有点不洁。我正在考虑添加另一个虚拟方法。(亚格尼?这不仅会遍历字段,还会评估备用过滤器是否成功。例如。我想知道是否有更好的模式来劫持函数列表。我目前的钩子列表($this->__filter)交换不适合链接。嗯,实际上,->xor 示例不需要迭代/行为与 ->array 完全相同。->xor
$_REQUEST->array->xor->email->url["fields"]
所以具体来说,我有兴趣找到一种替代我的 $this->__filter 列表用法的 array_pop() 和偷偷摸摸地把它换掉。这很糟糕。有没有更好的实现方案来执行方法列表一半是我>一半是你?
答:
我之前做过一个类似的链接接口,我喜欢你在 GET/POST 变量上使用它的想法。
我认为你最好做这样的事情
$var->array->email_XOR_url;而不是.这样你就可以用你的__get/__call魔法捕捉各种组合。
$var->array->email->XOR->url;
评论
->xor(var, filter1, filter2, filter3)
评论
$_GET->name->text;
$_GET["field"]