【问题标题】:PHP - Solving problems with Closures and ReflectionPHP - 解决闭包和反射问题
【发布时间】: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


【解决方案1】:

我喜欢这个基本的想法。但是实施非常糟糕。想象一下,我设置了nav=../../../../../../etc/passwd。这将(取决于您的服务器配置)允许我访问您的密码文件,这当然不好。

【讨论】:

  • 当然,这只是一个示例,不是完整的实现,我应该在底部进行一些安全检查。
  • 呃,我希望在 top (在包含原始文件之前,在 PHP 中会直接将它们发送到 STDOUT / 用户)。
猜你喜欢
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2012-07-15
  • 1970-01-01
  • 2012-06-17
  • 2016-05-03
  • 2012-06-21
相关资源
最近更新 更多