Мне нужно иметь возможность вызывать функцию, но имя функции хранится в переменной, это возможно? например:
функция foo () { // код здесь } функциональная панель () { // код здесь } $ functionName = "foo"; // мне нужно вызвать функцию в зависимости от значения $ functionName
php
dynamic-function
ящерица
источник
источник
is_callable
функцию. Он проверит, содержит ли переменная что-то, что может быть вызвано как функция (будь то имя функции, массив, содержащий экземпляр объекта и имя функции, или анонимная функция / замыкание)call_user_func(array('ClassName', 'method'), $args)
Моя любимая версия - встроенная версия:
Вы можете поместить переменные или выражения в скобки тоже!
источник
{"functionName"}();
недопустима и выдаст синтаксическую ошибку.Да, это возможно:
Источник: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
источник
Как уже упоминалось, есть несколько способов достичь этого, возможно, самым безопасным способом,
call_user_func()
или, если необходимо, вы также можете пойти по пути$function_name()
. Можно передать аргументы, используя оба этих метода, такЕсли вызываемая вами функция принадлежит объекту, вы все равно можете использовать любой из этих
Однако, если вы собираетесь использовать
$function_name()
метод, может быть хорошей идеей проверить наличие функции, если имя каким-либо образом является динамическимисточник
В случае, если Google привел сюда кого-то еще, потому что он пытался использовать переменную для метода в классе, ниже приведен пример кода, который действительно будет работать. Ничто из вышеперечисленного не сработало для моей ситуации. Основное различие заключается
&
в объявлении$c = & new...
и&$c
передачеcall_user_func
.Мой конкретный случай - при реализации чьего-либо кода, связанного с цветами и двумя методами-членами,
lighten()
иdarken()
из класса csscolor.php. По какой-то причине я хотел, чтобы один и тот же код мог вызывать светлее или темнее, а не выделять его с помощью логики. Это может быть результатом моего упрямства не просто использовать if-else или изменить код, вызывающий этот метод.Обратите внимание, что попытка чего-либо с
$c->{...}
не работает. Прочитав материалы, предоставленные читателями внизу страницы php.netcall_user_func
, я смог собрать все вышеперечисленное. Также обратите внимание, что$params
как массив не работал для меня:Приведенная выше попытка выдаст предупреждение о методе, ожидающем 2-й аргумент (проценты).
источник
Несколько лет спустя, но сейчас это лучший способ imho:
источник
Для полноты картины вы также можете использовать eval () :
Тем не менее,
call_user_func()
это правильный путь.источник
eval
не является решением этого вопроса.Решение: использовать PHP7
Примечание: для краткой версии см. TL; DR в конце ответа.
Старые Методы
Обновление : один из старых методов, описанных здесь, был удален. Обратитесь к другим ответам для объяснения других методов, здесь это не рассматривается. Кстати, если этот ответ вам не поможет, вам следует вернуться к обновлению вашего материала. Поддержка PHP 5.6 прекратилась в январе 2019 года (теперь даже PHP 7.0 и 7.1 не поддерживаются). Смотрите поддерживаемые версии для получения дополнительной информации.
Как уже упоминалось, в PHP5 (а также в более новых версиях, таких как PHP7) мы могли использовать переменные в качестве имен функций, использовать
call_user_func()
иcall_user_func_array()
(которые, лично я ненавижу эти функции) и т. Д.Новые Методы
Начиная с PHP7, появились новые способы:
Примечание. Все, что в
<something>
скобках, означает одно или несколько выражений для формирования чего-либо, например,<function_name>
означает выражения, образующие имя функции.Динамический вызов функции: имя функции на лету
Мы можем использовать одно или несколько выражений в скобках в качестве имени функции всего за один раз, в виде:
Например:
Примечание. Хотя удаление скобок
str_replace()
не является ошибкой, добавление скобок делает код более читабельным. Тем не менее, вы не можете сделать это иногда, например, при использовании.
оператора. Чтобы быть последовательным, я рекомендую ставить круглые скобки всегда.Динамический вызов метода: имя метода на лету
Так же, как динамические вызовы функций, мы можем сделать то же самое с вызовами методов, заключенными в фигурные скобки вместо скобок (для дополнительных форм перейдите к разделу TL; DR):
Смотрите это в примере:
Динамический вызов метода: синтаксис массива
В PHP7 добавлен более элегантный способ:
Например:
Примечание . Преимущество использования этого метода перед предыдущим заключается в том, что вам не важен тип вызова (т. Е. Статический он или нет).
Дополнительный пример: использование анонимных классов
Делая вещи немного сложнее, вы можете использовать комбинацию анонимных классов и описанных выше функций:
TL; DR (Заключение)
Как правило, в PHP7 возможно использование следующих форм:
Основано в основном на этом разговоре PHP .
источник
(expressions)->$bar()
Динамические имена функций и пространства имен
Просто добавить пункт о динамических именах функций при использовании пространств имен.
Если вы используете пространства имен, следующее не будет работать, если только ваша функция не находится в глобальном пространстве имен:
Что делать?
Вы должны использовать
call_user_func()
вместо:источник
В дополнение к ответу @Chris K, если вы хотите вызвать метод объекта, вы можете вызвать его с помощью одной переменной с помощью замыкания:
Я разместил еще один пример здесь
источник
Что я узнал из этого вопроса и ответов. Спасибо всем!
Допустим, у меня есть эти переменные и функции:
Для вызова функции без аргументов
Для вызова функции с 1 аргументом
Вызов функции с 1 или более аргументами. Это будет полезно, если вы динамически вызываете свои функции и каждая функция имеет разное количество аргументов. Это мой случай, который я искал (и раскрыл).
call_user_func_array
это ключYay пока!
источник
Используйте функцию call_user_func.
источник
Следующий код может помочь написать динамическую функцию в PHP. теперь имя функции можно динамически изменять с помощью переменной '$ current_page'.
источник
$function
переменную без каких-либо причин.Самый простой способ безопасного вызова функции с использованием имени, хранящегося в переменной:
Я использовал, как показано ниже, для динамического создания таблиц миграции в Laravel,
источник
Один необычный подход, который мне пришёл в голову, заключается в том, что, если вы не генерируете весь код с помощью какого-либо супер-ультра-автономного ИИ, который пишет сам , есть большие шансы, что функции, которые вы хотите «динамически» вызывать, уже определены в вашем коде. основание. Так почему бы просто не проверить строку и не позорить незнакомый
ifelse
танец, чтобы вызвать ... вы поняли мою точку зрения.например.
Даже
switch-case
можно использовать, если вам не нравится мягкий вкусifelse
лестницы.Я понимаю, что есть случаи, когда « динамический вызов функции » был бы абсолютной необходимостью ( подобно некоторой рекурсивной логике, которая модифицирует себя ). Но большинство повседневных тривиальных сценариев использования можно просто избежать.
Он отсеивает большую неопределенность в вашем приложении, давая вам возможность выполнить резервную функцию, если строка не соответствует определению какой-либо из доступных функций. ПО МОЕМУ МНЕНИЮ.
источник
if (method_exists($functionName)) $functionName(); else //exception or handle
Я не знаю, почему вы должны это использовать, мне это не очень хорошо звучит, но если есть только небольшое количество функций, вы можете использовать конструкцию if / elseif. Я не знаю, возможно ли прямое решение.
что-то вроде $ foo = "bar"; $ test = "foo"; эхо-тест $$;
должен вернуть бар, вы можете попробовать, но я не думаю, что это будет работать для функций
источник