多个同名的功能

时间:2014-05-03 02:05:13

标签: php include

我希望为我的网络应用程序创建一个扩展API。

示例扩展文件:

function echoCustomHeaders(){
    echo '<li><a href="./watever">Header Link</a></li>';
}

会有几个类似于示例扩展文件的文件(具有相同的函数名称,以便在编写插件时用户友好)。

for($x=0;$x<count($extension_files);$x++){
    //This would obviosely break when it gets to the second file, as functions cannot be declared twice in php
    require_once($extension_files[$x]);
}
//some code later...

//this should call echoCustomHeaders() in ALL of the extension files, what code should I put here to make this happen?
echoCustomHeaders();

如果您想知道问题是什么,请阅读上面代码中的注释,它应该很容易看到。

2 个答案:

答案 0 :(得分:1)

在扩展文件中返回闭包(lambda表达式),如下所示:

return function(){
    echo '<li><a href="./whatever">Header Link</a></li>';
}

在PHP中,include / require语句实际上是一个函数,因此具有返回值,因此您可以将这些闭包收集到一个数组中:

$closures = array();
for($x=0;$x<count($extension_files);$x++){
    $closures[$i]=include($extension_files[$x]);
}

// Do whatever you want with your closures, e.g. execute them:
foreach($closures as $closure) {
    $closure();
}

添加内容:

如果你想为每个include返回多个闭包,你可以返回一个闭包数组,用它们的名称索引:

return array(
  'echoCustomHeaders' => function() {
    echo '<li><a href="./whatever">Header Link</a></li>';
  },
  // ...
);

然后你仍然可以通过他们的名字执行其中一些:

$closureArray = array();
foreach($extension_files as $file) {
    $closureArray[] = include($file);
}

foreach($closureArray as $closure) {
    if(isset($closure['echoCustomHeaders'])) // Maybe there wasn't an echoCustomHeaders in each extension file ...
        $closure['echoCustomHeaders']();
}

甚至将不同类型的扩展函数分成不同的数组也是一个更好的主意:

$closureArray = array();
foreach($extension_files as $file) {
    $functions = include($file);
    foreach($functions as $name => $function) {
        if(!isset($closureArray[$name]))
            $closureArray[$name] = array();
        $closureArray[$name][] = $function;
    }
}

foreach($closureArray['echoCustomHeaders'] as $closure) {
        $closure();
}

另一种解决方案是使用更面向对象的方式,并在每个扩展文件中声明一个新的扩展类。但是,如果扩展文件中的扩展方法之间不需要数据共享,那么在我看来,简单地将函数作为闭包数组返回是一种更轻量级,更清晰的解决方案。

答案 1 :(得分:0)

1.可以在php5.3:namespace http://www.php.net/manual/en/language.namespaces.php之后使用新功能,然后就可以使用相同的名称功能了。 2.无论如何,您可以考虑面向对象的解决方案,例如,定义一个具有方法echoCustomHeaders的基类。