【发布时间】:2011-05-05 05:27:05
【问题描述】:
我需要创建必须由应用程序自动实现的动态面包屑。所以我在导航的 URL 中有以下结构: nav=user.listPMs.readPM&args=5
然后我可以有一个函数文件,其唯一目的是定义 user.listPMs.readPM 函数本身:
文件:nav/user.listPMs.readPM.php
function readPM($msgId)
{
/*code here*/
}
当然,这最终会使全局范围变得混乱,因为我没有使用类或使用命名空间来包装函数。这里最好的解决方案似乎是命名空间,毫无疑问对吧?但我也想到了另一个:
文件:nav/user.listPMs.readPM.php
return function($msgId)
{
/*code here*/
};
是的,很简单,文件只是返回一个匿名函数。我认为这很神奇,因为我不需要关心命名它——因为我已经正确命名了包含它的文件,创建了一个用户函数,但不得不命名它似乎只是多余的。然后在索引中我会有这个肮脏的小把戏:
文件:index.php
if($closure = @(include 'nav/'.$_GET['nav']))
{
if($closure instanceof Closure)
{
$obj = new ReflectionFunction($closure);
$args = explode(',',@$_GET['args']);
if($obj->getNumberOfParameters($obj)<=count($args))
call_user_func_array($closure,$args);
else
die('Arguments not matching or something...');
} else {
die('Bad call or something...');
}
} else {
die('Bad request etc.');
}
甚至无需提及,稍后只需解析 $_GET['nav'] 变量中的值即可很好地构建面包屑。
那么,您认为有没有更好的解决方案来解决这个问题?您是否找到了另一种探索闭包和/或反射的方法?
【问题讨论】:
-
请不要依赖
instanceof Closure的闭包。这是一个内部实现细节,手册明确要求您不要使用它,因为它可能在未来发生变化。 -
没错,我忘了在 php.net 上做作业。谢谢你的提醒!所以我将使用 is_callable($closure) 代替
标签: php reflection namespaces closures code-organization