如何从存储在变量中的字符串调用函数?
我需要能够调用函数,但函数名称存储在变量中,这可能吗? 例如:
function foo ()
{
//code here
}
function bar ()
{
//code here
}
$functionName = "foo";
// I need to call the function based on what is $functionName
I need to be able to call a function, but the function name is stored in a variable, is this possible? e.g:
function foo ()
{
//code here
}
function bar ()
{
//code here
}
$functionName = "foo";
// I need to call the function based on what is $functionName
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
以下代码可以帮助在 PHP 中编写动态函数。
现在函数名称可以通过变量“$current_page”动态更改。
Following code can help to write dynamic function in PHP.
now the function name can be dynamically change by variable '$current_page'.
考虑到这里给出的一些优秀答案,有时您需要精确。
例如。
ETC)。
让我们看看它对给出的一些答案的贡献。
我们想要检查方法是否存在并动态调用它。
谢谢
Considering some of the excellent answers given here, sometimes you need to be precise.
For example.
e.t.c).
Let's look at its credit to some of the answers given.
We want to check if method exists and call it dynamically.
Thanks
我想到的一种非常规方法是,除非您通过一些自行编写的超级超自主人工智能生成整个代码,否则您想要“动态”调用的函数很有可能,已在您的代码库中定义。 那么为什么不直接检查字符串并跳出臭名昭著的
ifelse
舞蹈来召唤......你明白我的意思了。例如。
如果您不喜欢
ifelse
梯子的平淡味道,甚至可以使用switch-case
。我理解,在某些情况下,“动态调用函数”是绝对必要的(就像一些自我修改的递归逻辑)。 但大多数日常琐碎用例都可以回避。
它消除了应用程序中的许多不确定性,同时在字符串与任何可用函数的定义不匹配时让您有机会执行后备函数。 恕我直言。
One unconventional approach, that came to my mind is, unless you are generating the whole code through some super ultra autonomous AI which writes itself, there are high chances that the functions which you want to "dynamically" call, are already defined in your code base. So why not just check for the string and do the infamous
ifelse
dance to summon the ...you get my point.eg.
Even
switch-case
can be used if you don't like the bland taste ofifelse
ladder.I understand that there are cases where the "dynamically calling the function" would be an absolute necessity (Like some recursive logic which modifies itself). But most of the everyday trivial use-cases can just be dodged.
It weeds out a lot of uncertainty from your application, while giving you a chance to execute a fallback function if the string doesn't match any of the available functions' definition. IMHO.
我不知道为什么你必须使用它,对我来说听起来不太好,但如果只有少量函数,你可以使用 if/elseif 结构。
不知道是否可以直接解决。
就像是
$foo = "酒吧";
$测试=“foo”;
回显$$测试;
应该返回 bar,你可以尝试一下,但我认为这不适用于函数
I dont know why u have to use that, doesnt sound so good to me at all, but if there are only a small amount of functions, you could use a if/elseif construct.
I dont know if a direct solution is possible.
something like
$foo = "bar";
$test = "foo";
echo $$test;
should return bar, you can try around but i dont think this will work for functions
$functionName()
或call_user_func($functionName)
如果您需要提供存储在另一个变量中的参数(以数组的形式),使用 数组解包运算符:
动态创建对象并调用其方法
或调用静态方法
$functionName()
orcall_user_func($functionName)
If you need to provide parameters stored in another variable (in the form of array), use array unpacking operator:
To dynamically create an object and call its method use
or to call a static method
我最喜欢的版本是内联版本:
您也可以将变量或表达式放在括号内!
My favorite version is the inline version:
You can place variables or expressions inside the brackets too!
解决方案:使用 PHP7
注意: 有关汇总版本,请参阅答案末尾的 TL;DR。
旧方法
更新:此处解释的旧方法之一已被删除。 其他方法的解释可以参考其他答案,这里不再赘述。 顺便说一句,如果这个答案对您没有帮助,您应该返回升级您的东西。 PHP 5.6 支持已于 2019 年 1 月终止(现在甚至不支持 PHP 7.2 和 7.3)。 有关详细信息,请参阅支持的版本。
正如其他人提到的,在 PHP5(以及 PHP7 等较新版本)中,我们可以使用变量作为函数名称,使用
call_user_func()
和call_user_func_array()
等。
从 PHP7 开始,引入了新的方法:
注意:
括号内的所有内容都表示一个或多个表达式来形成某物,例如。
表示形成函数名称的表达式。动态函数调用:即时函数名称
我们可以一次性在括号内形成一个函数名称:
例如:
注意:尽管删除了
str_replace()
不是错误,添加括号可以使代码更具可读性。 但是,有时您不能这样做,例如在使用.
运算符时。 为了保持一致,我建议您始终添加括号。动态函数调用:可调用属性
一个有用的示例是在对象的上下文中:如果您在属性中存储了可调用对象,则必须以这种方式调用它:
作为一个简单的示例:
显然,将其调用为
$this ->eventHandler()
是完全错误的:您的意思是调用名为eventHandler
的方法。动态方法调用:动态方法名称
就像动态函数调用一样,我们可以对方法调用执行相同的操作,用大括号而不是圆括号括起来(对于其他形式,请导航至 TL;DR 部分):
请参阅示例:
动态方法调用:数组语法
PHP7 中添加的一种更优雅的方法如下:
作为示例:
注意: 与前一种方法相比,使用此方法的好处是,您不必不关心调用类型(即是否是静态的)。
注意:如果您关心性能(和微优化),请不要使用此方法。 据我测试,这个方法确实比其他方法慢(10倍以上)。
额外示例:使用匿名类
让事情变得有点复杂,您可以使用 的组合匿名类以及上面的功能:
TL;DR(结论)
一般来说,在PHP7中,使用以下形式都是可以的:
特别感谢这个 PHP 演讲。
Solution: Use PHP7
Note: For a summarized version, see TL;DR at the end of the answer.
Old Methods
Update: One of the old methods explained here has been removed. Refer to other answers for explanation on other methods, it isn't covered here. By the way, if this answer doesn't help you, you should return upgrading your stuff. PHP 5.6 support has ended in January 2019 (now even PHP 7.2 and 7.3 are not being supported). See supported versions for more information.
As others mentioned, in PHP5 (and also in newer versions like PHP7) we could use variables as function names, use
call_user_func()
andcall_user_func_array()
, etc.New Methods
As of PHP7, there are new ways introduced:
Note: Everything inside
<something>
brackets means one or more expressions to form something, e.g.<function_name>
means expressions forming a function name.Dynamic Function Call: Function Name On-the-fly
We can form a function name inside parentheses in just one go:
For example:
Note: Although removing the parentheses around
str_replace()
is not an error, putting parentheses makes code more readable. However, you cannot do that sometimes, e.g. while using.
operator. To be consistent, I recommend you to put the parentheses always.Dynamic Function Call: Callable Property
A useful example would be in the context of objects: If you have stored a callable in a property, you have to call it this way:
As a simple example:
Obviously, calling it as
$this->eventHandler()
is plain wrong: By that you mean calling a method namedeventHandler
.Dynamic Method Call: Method Name On-the-fly
Just like dynamic function calls, we can do the same way with method calls, surrounded by curly braces instead of parentheses (for extra forms, navigate to TL;DR section):
See it in an example:
Dynamic Method Call: The Array Syntax
A more elegant way added in PHP7 is the following:
As an example:
Note: The benefit of using this method over the previous one is that, you don't care about the call type (i.e. whether it's static or not).
Note: If you care about performance (and micro-optimizations), don't use this method. As I tested, this method is really slower than other methods (more than 10 times).
Extra Example: Using Anonymous Classes
Making things a bit complicated, you could use a combination of anonymous classes and the features above:
TL;DR (Conclusion)
Generally, in PHP7, using the following forms are all possible:
Special thanks to this PHP talk.
是的,这是可能的:
来源:http ://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
Yes, it is possible:
Source: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
如前所述,有几种方法可以实现此目的,其中最安全的方法可能是
call_user_func()
,或者如果必须的话,您也可以沿着$function_name()
的路线进行>。 可以使用这两种方法传递参数,因此如果您调用的函数属于一个对象,您仍然可以使用其中任何一个
但是如果您要使用
$function_name()
方法如果名称是动态的,则测试该函数是否存在可能是个好主意As already mentioned, there are a few ways to achieve this with possibly the safest method being
call_user_func()
or if you must you can also go down the route of$function_name()
. It is possible to pass arguments using both of these methods as soIf the function you are calling belongs to an object you can still use either of these
However if you are going to use the
$function_name()
method it may be a good idea to test for the existence of the function if the name is in any way dynamic晚了几年,但恕我直言,这是现在最好的方式:
A few years late, but this is the best manner now imho:
如果其他人被谷歌带到这里,因为他们试图在类中使用变量作为方法,下面是一个实际有效的代码示例。 以上都不适合我的情况。 主要区别在于
$c = & 声明中的
和&
new...&$c
在call_user_func
中传递。我的具体情况是,当实现某人与颜色有关的代码以及 csscolor.php 类中的两个成员方法
lighten()
和darken()
时。 无论出于何种原因,我希望相同的代码能够调用变亮或变暗,而不是通过逻辑选择它。 这可能是由于我固执地不只使用 if-else 或更改调用此方法的代码的结果。请注意,尝试使用
$c->{...}
进行任何操作均无效。 在仔细阅读了call_user_func
php.net 页面底部的读者提供的内容后,我能够将上述内容拼凑起来。 另请注意,$params
作为数组对我不起作用:上述尝试将给出有关需要第二个参数(百分比)的方法的警告。
In case someone else is brought here by google because they were trying to use a variable for a method within a class, the below is a code sample which will actually work. None of the above worked for my situation. The key difference is the
&
in the declaration of$c = & new...
and&$c
being passed incall_user_func
.My specific case is when implementing someone's code having to do with colors and two member methods
lighten()
anddarken()
from the csscolor.php class. For whatever reason, I wanted to have the same code be able to call lighten or darken rather than select it out with logic. This may be the result of my stubbornness to not just use if-else or to change the code calling this method.Note that trying anything with
$c->{...}
didn't work. Upon perusing the reader-contributed content at the bottom of php.net's page oncall_user_func
, I was able to piece together the above. Also, note that$params
as an array didn't work for me:This above attempt would give a warning about the method expecting a 2nd argument (percent).
为了完整起见,您还可以使用 eval():
但是,
call_user_func()
是正确的方法。For the sake of completeness, you can also use eval():
However,
call_user_func()
is the proper way.动态函数名称和命名空间
只是在使用命名空间时添加有关动态函数名称的一点。
如果您使用命名空间,除非您的函数位于全局命名空间中,否则以下操作将不起作用:
该怎么办?
您必须使用
call_user_func()
来代替:Dynamic function names and namespaces
Just to add a point about dynamic function names when using namespaces.
If you're using namespaces, the following won't work except if your function is in the global namespace:
What to do?
You have to use
call_user_func()
instead:补充@Chris K的答案,如果你想调用一个对象的方法,你可以在闭包的帮助下使用单个变量来调用它:
我发布了另一个例子这里
Complementing the answer of @Chris K if you want to call an object's method, you can call it using a single variable with the help of a closure:
I posted another example here
使用 call_user_func 函数。
Use the call_user_func function.
我从这个问题和答案中学到了什么。 谢谢大家!
假设我有这些变量和函数:
调用函数不带参数
<块引用>
你好!
使用 1 个参数调用函数
<块引用>
亲爱的约翰,你好!
使用 1 个或多个参数调用函数
如果您动态调用函数并且每个函数具有不同数量的参数,这将很有用。 这是我一直在寻找(并解决)的案例。
call_user_func_array
是关键<块引用>
亲爱的莎拉,你好吗?
耶再见!
What I learnt from this question and the answers. Thanks all!
Let say I have these variables and functions:
To call function without arguments
To call function with 1 argument
To call function with 1 or more arguments
This will be useful if you are dynamically calling your functions and each function have different number of arguments. This is my case that I have been looking for (and solved).
call_user_func_array
is the keyYay bye!
如果您在对象上下文中尝试动态调用函数,请尝试如下代码:
If you were in a object context trying to call a function dynamically please try something like this code bellow:
使用存储在变量中的名称安全地调用函数的最简单方法是,
我使用如下方式在 Laravel 中动态创建迁移表,
The easiest way to call a function safely using the name stored in a variable is,
I have used like below to create migration tables in Laravel dynamically,