我需要能够调用一个函数,但函数名存储在一个变量,这是可能的吗?例句:
function foo ()
{
//code here
}
function bar ()
{
//code here
}
$functionName = "foo";
// I need to call the function based on what is $functionName
我需要能够调用一个函数,但函数名存储在一个变量,这是可能的吗?例句:
function foo ()
{
//code here
}
function bar ()
{
//code here
}
$functionName = "foo";
// I need to call the function based on what is $functionName
当前回答
$functionName()或call_user_func($functionName)
其他回答
使用call_user_func函数。
解决方案:使用PHP7
注意:关于总结版本,请参见答案末尾的TL;DR。
老方法
更新:这里解释的一个旧方法已被删除。关于其他方法的解释,请参考其他答案,这里不涉及。顺便说一下,如果这个答案对你没有帮助,你应该回来升级你的东西。对PHP 5.6的支持已于2019年1月结束(现在甚至不支持PHP 7.2和7.3)。有关更多信息,请参阅支持的版本。
正如其他人所提到的,在PHP5(以及像PHP7这样的新版本)中,我们可以使用变量作为函数名,使用call_user_func()和call_user_func_array()等。
新方法
从PHP7开始,引入了新的方法:
注意:<something>括号内的所有内容都表示一个或多个表达式组成一个东西,例如<function_name>表示表达式组成一个函数名。
动态函数调用:动态函数名
我们可以在括号内创建一个函数名:
(<function_name>)(arguments);
例如:
function something(): string
{
return "something";
}
$bar = "some_thing";
(str_replace("_", "", $bar))(); // something
// Possible, too; but generally, not recommended, because makes your
// code more complicated
(str_replace("_", "", $bar))()();
注意:尽管删除str_replace()周围的圆括号并不是错误,但添加圆括号会使代码更具可读性。然而,有时你不能这样做,例如在使用时。操作符。为了保持一致,我建议您始终使用括号。
动态函数调用:可调用属性
一个有用的例子是在对象的上下文中:如果你在属性中存储了一个可调用对象,你必须这样调用它:
($object->{<property_name>})();
举个简单的例子:
// Suppose we're in a class method context
($this->eventHandler)();
显然,调用它为$this->eventHandler()是完全错误的:你的意思是调用一个名为eventHandler的方法。
动态方法调用:动态方法名
就像动态函数调用一样,我们也可以用同样的方法调用方法,用花括号括起来,而不是圆括号(对于额外的表单,请导航到TL;DR部分):
$object->{<method_name>}(arguments);
$object::{<method_name>}(arguments);
请看一个例子:
class Foo
{
public function another(): string
{
return "something";
}
}
$bar = "another thing";
(new Something())->{explode(" ", $bar)[0]}(); // something
动态方法调用:数组语法
PHP7中增加了一种更优雅的方式:
[<object>, <method_name>](arguments);
[<class_name>, <method_name>](arguments); // Static calls only
举个例子:
class Foo
{
public function nonStaticCall()
{
echo "Non-static call";
}
public static function staticCall()
{
echo "Static call";
}
}
$x = new X();
[$x, "non" . "StaticCall"](); // Non-static call
[$x, "static" . "Call"](); // Static call
注意:使用这个方法的好处是,你不关心调用类型(即它是否是静态的)。
注意:如果您关心性能(和微优化),请不要使用此方法。在我的测试中,这个方法确实比其他方法慢(超过10倍)。
额外示例:使用匿名类
让事情变得有点复杂,你可以结合使用匿名类和上面的特性:
$bar = "SomeThing";
echo (new class {
public function something()
{
return 512;
}
})->{strtolower($bar)}(); // 512
TL(结论)博士;
一般来说,在PHP7中,使用下列形式都是可能的:
// Everything inside `<something>` brackets means one or more expressions
// to form something
// Dynamic function call via function name
(<function_name>)(arguments);
// Dynamic function call on a callable property
($object->{<property_name>})(arguments);
// Dynamic method call on an object
$object->{<method_name>}(arguments);
$object::{<method_name>}(arguments);
// Dynamic method call on a dynamically-generated object
(<object>)->{<method_name>}(arguments);
(<object>)::{<method_name>}(arguments);
// Dynamic method call, statically
ClassName::{<method_name>}(arguments);
(<class_name>)::{<method_name>}(arguments);
// Dynamic method call, array-like (no different between static
// and non-static calls
[<object>, <method_name>](arguments);
// Dynamic method call, array-like, statically
[<class_name>, <method_name>](arguments);
特别感谢这次PHP讲座。
我不知道你为什么要用它,听起来对我来说一点都不好,但如果只有少量的函数,你可以使用if/elseif结构。 我不知道是否有直接的解决办法。
类似的 $foo = "bar"; $test = "foo"; echo $ $测试;
应该返回酒吧,你可以尝试,但我不认为这将工作的功能
考虑到这里给出的一些很好的答案,有时你需要精确。 为例。
如果一个函数有返回值,例如(boolean,array,string,int,float e.t.c)。 如果函数没有返回值,则检查 如果函数存在
让我们来看看这些答案的可信度。
Class Cars{
function carMake(){
return 'Toyota';
}
function carMakeYear(){
return 2020;
}
function estimatedPriceInDollar{
return 1500.89;
}
function colorList(){
return array("Black","Gold","Silver","Blue");
}
function carUsage(){
return array("Private","Commercial","Government");
}
function getCar(){
echo "Toyota Venza 2020 model private estimated price is 1500 USD";
}
}
我们想要检查方法是否存在并动态调用它。
$method = "color List";
$class = new Cars();
//If the function have return value;
$arrayColor = method_exists($class, str_replace(' ', "", $method)) ? call_user_func(array($this, $obj)) : [];
//If the function have no return value e.g echo,die,print e.t.c
$method = "get Car";
if(method_exists($class, str_replace(' ', "", $method))){
call_user_func(array($class, $method))
}
谢谢
如果有人被谷歌带到这里,因为他们试图在一个类中使用一个方法的变量,下面是一个实际工作的代码示例。以上这些方法都不适用于我的情况。关键的区别在于$c = & new…&$c在call_user_func中传递。
我的具体情况是当实现某人的代码必须与颜色和两个成员方法点亮()和暗()从csscolor.php类。不管出于什么原因,我希望有相同的代码能够调用变亮或变暗,而不是用逻辑选择它。这可能是我固执地不使用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->{…不管用。通过阅读php.net页面底部call_user_func上的读者提供的内容,我能够将上述内容拼凑在一起。另外,请注意$params作为数组对我不起作用:
// This doesn't work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);
上述尝试将给出关于该方法期望第二个参数(percent)的警告。