如何在PHP中为函数设置别名?

66

在PHP中,是否可以将函数用不同的名称进行别名处理?假设我们有一个名为 sleep 的函数。是否有方法可以创建一个名为 wait 的别名?

目前我是这样做的:

function wait( $seconds ) {
    sleep($seconds);
}
16个回答

71

在 PHP 5.5 之前

没错,function wait ($seconds) { sleep($seconds); } 是正确的方法。但是如果你担心需要改变 wait() 函数,例如当 sleep() 的参数数量发生变化时,那么你可以考虑使用下面的方法:

function wait() { 
  return call_user_func_array("sleep", func_get_args());
}

14
只有在PHP > 5.3中,func_get_args()才能在参数列表中使用,像这样工作。在PHP < 5.3中,您需要使用临时变量:$args = func_get_args(); return call_user_unc_array('sleep', $args); - Marko
这是我首选的答案,因为它还允许您在类内部别名静态方法,例如:call_user_func_array(array("Class", "staticMethod"), func_get_args()); - OCDev
@FriendlyDev,你为什么不直接使用call_user_func_array("TheClass::theStaticMethod", func_get_args());呢? - DiegoDD
如果你想要非常高级的实现,可以使用 return sleep(...func_get_args()); - Brian Leishman
@AbiusX 我有一个函数,其中第一个变量是按引用传递的,因此这对于该函数有效。function v(&$v) { return Validate($v, ...array_slice(func_get_args(), 1)); } - Brian Leishman

67

仅适用于PHP 5.6+

从PHP 5.6开始,可以通过导入来将函数别名化:

use function sleep as wait;

文档中还有一个示例(请参见“别名函数”):documentation


11
这个类的方法看起来会是什么样子? - Nathan J.B.
5
以下是我所知道的所有方法(包括不好的方法)来给一个类的方法设置别名,包括静态和非静态方法:https://gist.github.com/nathanbrauer/cdd286351f68a1b4e3a5 - Nathan J.B.
1
我想在我的类中为使用该类的人提供有用的别名。有时这是一种优雅的弃用方式(例如,框架的早期版本拼错了方法),而其他时候则只是良好的用户体验。 - Nathan J.B.
1
如果在过程化上下文中的一个包含文件中使用,它似乎无法全局工作。 - Vincent Poirier
4
@VincentPoirier,导入是按文件的方式进行的,因此另一个文件无法为您重新定义函数。 - Jon
显示剩余3条评论

30

不行,但你可以这样做:

$wait = 'sleep';
$wait($seconds);

这样做还可以解决参数数量问题。


2
变量变量可能会变得非常混乱。我认为这不是解决这个问题的最佳方法。 - GSto
5
@GSto 这并不是最佳解决方案,仅仅是一个可能性。我简直不敢相信它被赞了这么多次 :-) - Federico klez Culloca
在PHP中,另一个字符串内容被替换了多少?看起来像是每个变量都集成了eval()。就像混合解析器、预处理器和解释器融为一体的一种非常糟糕设计的语言。注意:我不是PHP程序员(C ++,Python和Javascript)。 - Brian Cannard
1
这种类型的结构是我当初开始使用PHP的原因。简单易读,而且几乎所有东西都能实现。我依然喜爱它。 - Oliver Manner

23

如果你使用的是PHP 5.3,你也可以查看lambda表达式

$wait = function($v) { return sleep($v); };

9
如果您不介意使用PHP的"eval"指令(许多人对此有很大的问题,但我并不是),那么您可以使用类似于以下内容的东西:
function func_alias($target, $original) {
    eval("function $target() { \$args = func_get_args(); return call_user_func_array('$original', \$args); }");
}

我在一些简单的测试中使用了它,似乎效果还不错。以下是一个示例:

function hello($recipient) {
    echo "Hello, $recipient\n";
}

function helloMars() {
    hello('Mars');
}

func_alias('greeting', 'hello');
func_alias('greetingMars', 'helloMars');

greeting('World');
greetingMars();

6
抱歉,PHP没有快速的方法来实现函数别名,除非编写包装函数。如果你真的需要这个功能,你可以编写一个PHP扩展来实现,但是使用该扩展需要编译和配置PHP,这将大大降低应用程序的可移植性。请参考此处了解更多信息。

2
您不一定需要重新编译 PHP。您可以编译模块,然后通过 php.ini 包含它。 - Kevin Peno
非常正确,Kevin。我已经更新了帖子以反映您的评论。 - Alana Storm

5
不,函数不是一等公民,所以没有像JavaScript中的wait = sleep那样的方法。你基本上必须按照你在问题中提出的方式进行操作:
function wait ($seconds) { sleep($seconds); }


4
function alias($function)
{
    return function (/* *args */) use ($function){
        return call_user_func_array( $function, func_get_args() );
    };
}

$uppercase = alias('strtoupper');
$wait      = alias('sleep');

echo $uppercase('hello!'); // -> 'HELLO!'

$wait(1); // -> …

3

如果你的PHP不支持use x as y语法,那么在旧版本的PHP中,你可以定义匿名函数

$wait = create_function('$seconds', 'sleep($seconds);');
$wait(1);

或者将代码放在常量内,例如:

define('wait', 'sleep(1);');
eval(wait);

参见:eval()的替代方案是什么?

如果您有很长的代码段,而且不想重复使用它,或者该代码对于新函数也没有用处,那么这就特别有用。


还有一个由Dave H发布的函数,非常适用于创建用户函数别名:

function create_function_alias($function_name, $alias_name) 
{ 
    if(function_exists($alias_name)) 
        return false; 
    $rf = new ReflectionFunction($function_name); 
    $fproto = $alias_name.'('; 
    $fcall = $function_name.'('; 
    $need_comma = false; 

    foreach($rf->getParameters() as $param) 
    { 
        if($need_comma) 
        { 
            $fproto .= ','; 
            $fcall .= ','; 
        } 

        $fproto .= '$'.$param->getName(); 
        $fcall .= '$'.$param->getName(); 

        if($param->isOptional() && $param->isDefaultValueAvailable()) 
        { 
            $val = $param->getDefaultValue(); 
            if(is_string($val)) 
                $val = "'$val'"; 
            $fproto .= ' = '.$val; 
        } 
        $need_comma = true; 
    } 
    $fproto .= ')'; 
    $fcall .= ')'; 

    $f = "function $fproto".PHP_EOL; 
    $f .= '{return '.$fcall.';}'; 

    eval($f); 
    return true; 
}

create_function()自PHP 7.2起已被弃用,并在PHP 8.0中删除。强烈不建议使用它。 - MAChitgarha
请参阅PHP中eval()何时是邪恶的 - MAChitgarha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接