Мне нужно иметь возможность вызывать функцию, но имя функции хранится в переменной, возможно ли это? например:
функция foo () { // код здесь } функциональная панель () { // код здесь } $ functionName = "foo"; // Мне нужно вызвать функцию, основанную на том, что такое $ functionName
Anyhelp будет здорово.
Благодаря!
$functionName()
или call_user_func($functionName)
Моя любимая версия – встроенная версия:
${"variableName"} = 12; $className->{"variableName"}; $className->{"methodName"}(); StaticClass::${"variableName"}; StaticClass::{"methodName"}();
Вы также можете разместить переменные или выражения внутри скобок!
Да, это возможно:
function foo($msg) { echo $msg."<br />"; } $var1 = "foo"; $var1("testing 1,2,3");
Источник: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
В случае, если кто-то еще привезет сюда Google, потому что они пытались использовать переменную для метода внутри класса, ниже приведен пример кода, который будет работать. Ничто из этого не помогло мне. Ключевым отличием является &
в объявлении $c = & new...
и &$c
, передаваемых в call_user_func
.
Моим конкретным случаем является реализация кода пользователя, связанного с цветами и двумя методами-членами lighten()
и darken darken()
из класса csscolor.php. По какой-то причине я хотел, чтобы один и тот же код мог вызвать lighten или darken, а не выбирать его с логикой. Это может быть результатом моего упрямства не просто использовать if-else, либо изменить код, вызывающий этот метод.
$lightdark="lighten"; // or optionally can be darken $color="fcc"; // a hex color $percent=0.15; include_once("csscolor.php"); $c = & new CSS_Color($color); $rtn=call_user_func( array(&$c,$lightdark),$color,$percent);
Обратите внимание, что попытка чего-либо с помощью $c->{...}
не работает. После ознакомления с содержанием, полученным читателем, в нижней части страницы call_user_func
на call_user_func
, я смог собрать вместе выше. Также обратите внимание, что $params
как массив не работает для меня:
// This doesn't work: $params=Array($color,$percent); $rtn=call_user_func( array(&$c,$lightdark),$params);
Эта вышеприведенная попытка даст предупреждение о методе, ожидающем второй аргумент (в процентах).
Для полноты вы также можете использовать eval () :
$functionName = "foo()"; eval($functionName);
Тем не менее, call_user_func()
является правильным способом.
Как уже упоминалось, есть несколько способов добиться этого, возможно, самым безопасным методом является call_user_func()
или если вы также можете пойти по пути $function_name()
. Можно передавать аргументы, используя оба этих метода, так как
$function_name = 'foobar'; $function_name(arg1, arg2); call_user_func_array($function_name, array(arg1, arg2));
Если функция, которую вы вызываете, принадлежит объекту, вы все равно можете использовать любой из этих
$object->$function_name(arg1, arg2); call_user_func_array(array($object, $function_name), array(arg1, arg2));
Однако, если вы собираетесь использовать метод $function_name()
может быть хорошей проверкой на существование функции, если имя каким-либо образом является динамическим
if(method_exists($object, $function_name)) { $object->$function_name(arg1, arg2); }
Несколько лет спустя, но это лучший способ теперь imho:
$x = (new ReflectionFunction("foo"))->getClosure(); $x();
Просто добавьте точку имен динамических функций при использовании пространств имен.
Если вы используете пространства имен, следующее не будет работать, кроме если ваша функция находится в глобальном пространстве имен:
namespace greetings; function hello() { // do something } $myvar = "hello"; $myvar(); // interpreted as "\hello();"
call_user_func()
этого вы должны использовать call_user_func()
:
// if hello() is in the current namespace call_user_func(__NAMESPACE__.'\\'.$myvar); // if hello() is in another namespace call_user_func('mynamespace\\'.$myvar);
Дополняя ответ @Chris K, если вы хотите вызвать метод объекта, вы можете вызвать его с помощью одной переменной с помощью закрытия:
function get_method($object, $method){ return function() use($object, $method){ $args = func_get_args(); return call_user_func_array(array($object, $method), $args); }; } class test{ function echo_this($text){ echo $text; } } $test = new test(); $echo = get_method($test, 'echo_this'); $echo('Hello'); //Output is "Hello"
Я добавил еще один пример
Используйте функцию call_user_func.
Следующий код может помочь написать динамическую функцию в PHP. теперь имя функции может динамически меняться переменной «$ current_page».
$current_page = 'home_page'; $function = @${$current_page . '_page_versions'}; $function = function() { echo 'current page'; }; $function();
Я не знаю, почему у вас это использовать, не так хорошо звучит для меня вообще, но если есть только небольшое количество функций, вы можете использовать конструкцию if / elseif. Я не знаю, возможно ли прямое решение.
что-то вроде $ foo = "bar"; $ test = "foo"; echo $$ test;
должен возвращать бар, вы можете попробовать, но я не думаю, что это будет работать для функций