Как псевдоним функции в PHP?

Можно ли использовать псевдоним функции с другим именем в PHP? Предположим, у нас есть функция с именем sleep. Есть ли способ сделать псевдоним wait?

Пока делаю так:

function wait( $seconds ) {
    sleep($seconds);
}

person Atif    schedule 06.11.2009    source источник


Ответы (14)


Только PHP 5.6+

Начиная с PHP 5.6 это можно использовать псевдоним функции, импортируя ее:

use function sleep as wait;

Пример также есть в документации. (см. «псевдоним функции»).

person Jon    schedule 02.05.2014
comment
Как это будет выглядеть для методов класса? - person Nathan J.B.; 27.09.2014
comment
@NathanJ.Brauer: Вы спрашиваете, как вызвать метод foo существующего объекта, используя имя bar, вызвать статический метод foo класса, используя имя bar, или что-то еще? Для двух случаев, которые я упомянул, краткий ответ: вы не можете. - person Jon; 10.10.2014
comment
Вот все способы (включая плохие), которые я знаю, для псевдонима метода класса, как статического, так и нет: noreferrer">gist.github.com/nathanbrauer/cdd286351f68a1b4e3a5 - person Nathan J.B.; 10.10.2014
comment
@NathanJ.Brauer: Все это предполагает, что вы владеете классом и можете вносить изменения. Но нет языковой фичи, позволяющей сделать это извне, как с use (function) X as Y. - person Jon; 10.10.2014
comment
Правильно - я хочу иметь возможность в своем собственном классе предоставлять полезные псевдонимы тем, кто использует класс. Иногда это средство изящного устаревания (например, в предыдущей версии фреймворка был метод с ошибкой), а иногда это просто хороший UX. - person Nathan J.B.; 11.10.2014
comment
Похоже, он не работает глобально, если используется внутри включенного файла в процедурном контексте. - person Vincent Poirier; 20.10.2015
comment
Импорт @VincentPoirier выполняется для каждого файла, другой файл не может переопределить функцию для вас. - person Jon; 20.10.2015
comment
Вы правы! Мой нос прилип к дереву сделать это глобальным. Я не мог видеть леса вокруг него. - person Vincent Poirier; 20.10.2015

До PHP 5.5

да, function wait ($seconds) { sleep($seconds); } это путь. Но если вы беспокоитесь о необходимости изменить wait(), если вы измените количество параметров для sleep(), вы можете вместо этого сделать следующее:

function wait() { 
  return call_user_func_array("sleep", func_get_args());
}
person Lukman    schedule 06.11.2009
comment
func_get_args() будет работать так только в PHP › 5.3, где вы можете использовать его в списке параметров. В PHP ‹ 5.3 вы должны использовать временную переменную: $args = func_get_args(); return call_user_unc_array('sleep', $args); - person Marko; 06.11.2009
comment
Это мой предпочтительный ответ, потому что он также позволяет использовать псевдоним статического метода внутри класса, например: call_user_func_array(array(Class, staticMethod), func_get_args()); - person OCDev; 20.02.2012
comment
@FriendlyDev не могли бы вы просто использовать call_user_func_array("TheClass::theStaticMethod", func_get_args()); вместо этого? - person DiegoDD; 16.08.2014
comment
Или, если вы хотите быть действительно модным, return sleep(...func_get_args()); - person Brian Leishman; 21.09.2017
comment
@AbiusX У меня была функция, в которой первая переменная была по ссылке, так что это работает для этого function v(&$v) { return Validate($v, ...array_slice(func_get_args(), 1)); } - person Brian Leishman; 18.12.2018

Нет, но вы можете сделать это:

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

Таким образом вы также решаете проблемы с числом аргументов.

person Federico klez Culloca    schedule 06.11.2009
comment
переменные переменные могут быть действительно запутанными. Я не думаю, что это лучший способ решить проблему здесь. - person GSto; 06.11.2009
comment
@GSto это не должно было быть лучшим решением. это была просто возможность. Я не могу поверить, что за это проголосовали так много :-) - person Federico klez Culloca; 06.11.2009
comment
Сколько другого содержимого строки заменяется таким образом в PHP? Похоже, что eval() интегрирован в каждую переменную. Как смешанный парсер, препроцессор и интерпретатор в один очень плохо спроектированный язык. Примечание. Я не программист PHP (C++, Python и Javascript). - person Brian Cannard; 12.05.2015
comment
Именно благодаря таким структурам я начал использовать PHP в свое время. Простой, понятный человеку и все возможно. Все еще люблю это. - person Oliver Manner; 05.12.2018

Вы также можете посмотреть лямбды если у вас PHP 5.3

$wait = function($v) { return sleep($v); };
person Ólafur Waage    schedule 06.11.2009

Если вас не интересует использование инструкции 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();
person Nathan Crause    schedule 20.05.2010

Нет, в PHP нет быстрого способа сделать это. Язык не предлагает возможности псевдонимов функций без написания функции-оболочки.

Если вам это действительно очень нужно, вы можете написать расширение PHP что бы сделать это для вас. Однако, чтобы использовать расширение, вам нужно будет скомпилировать ваше расширение и настроить PHP для использования этого расширения, что означает, что переносимость вашего приложения будет значительно снижена.

person Alan Storm    schedule 06.11.2009
comment
Вам не обязательно перекомпилировать php. Вместо этого вы можете скомпилировать модуль и включить его через php.ini. - person Kevin Peno; 06.11.2009
comment
Совершенно верно, Кевин, я обновил пост, чтобы отразить ваши комментарии. - person Alan Storm; 06.11.2009

Нет, функции не являются гражданами первого класса, поэтому нет wait = sleep, например, Javascript. Вы в основном должны делать то, что вы задали в своем вопросе:

function wait ($seconds) { sleep($seconds); }
person Greg    schedule 06.11.2009

вы можете использовать расширение runkit

http://us.php.net/manual/en/function.runkit-function-copy.php

person user187291    schedule 06.11.2009

Если ваш PHP не поддерживает используйте x вместо 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; 
}
person kenorb    schedule 17.03.2015

Нет. как вы написали, это лучший способ сделать это.

person GSto    schedule 06.11.2009

Нет, быстрого способа сделать это нет — по крайней мере, для чего-либо до PHP v5.3, и это тоже не очень хорошая идея. Это просто усложняет дело.

person Alister Bulman    schedule 06.11.2009

Начиная с PHP 5.6

Это особенно полезно для использования в классах с магическими методами.

class User extends SomethingWithMagicMethods {
    
    public function Listings(...$args) {
        return $this->Children(...$args);
    }

}

Но я почти уверен, что он работает и с обычными функциями.

function UserListings(...$args) {
    return UserChildren(...$args);
}

Источник: PHP: Новые возможности — › Функции Variadic через...

person Nathan J.B.    schedule 06.03.2017

Я знаю, что это старо, но ты всегда можешь

$wait = 'sleep';
$wait();
person Petruza    schedule 17.09.2015
comment
Разве это не эквивалентно этому существующему ответу? - person Pang; 06.05.2016
comment
@Pang Да, но моя память не настолько хороша, чтобы ответить, почему я сделал это несколько месяцев назад. - person Petruza; 08.05.2016

Что я использовал в своем КЛАССЕ

function __call($name, $args) {
    $alias['execute']=array('done','finish');
    $alias['query']=array('prepare','do');
    if (in_array($name,$alias['execute'])){
        call_user_func_array("execute",$args);
        return TRUE;
    }elseif(in_array($name,$alias['query'])){
        call_user_func_array("query",$args);
        return TRUE;
    }
    die($this->_errors.' Invalid method:'.$name.PHP_EOL);
}
person Abbas    schedule 21.07.2014