如何从存储在变量中的字符串调用PHP函数

How to call PHP function from string stored in a Variable

我需要能够调用一个函数,但是函数名存储在一个变量中,这是可能的吗?例如:

1
2
3
4
5
6
7
8
9
10
11
12
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)


我最喜欢的版本是内联版本:

1
2
3
4
5
6
${"variableName
<div class="
suo-content">[collapse title=""]<ul><li>@马西奥阿尔马达:发表评论,而不是用这种方式编辑别人的答案;这增加了困惑-不清楚谁说了什么[好奇者:解释见修订]</li><li>好的。第2行<wyn>{"functionName"}();</wyn>不合法,将引发语法错误。</li><li>感谢各位,对于这些回复,它确实会抛出一个错误,甚至在php 5.4中,所以语法只适用于对象方法。编辑了文章。</li><li>这让人困惑……它需要更多的解释它是做什么的。</li><li>哪一部分不是不言自明的?</li></ul>[/collapse]</div><p><center>[wp_ad_camp_1]</center></p><hr><P>是的,有可能:</P>[cc lang="php"]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?页面=2


如前所述,有几种方法可以实现这一点,其中最安全的方法可能是call_user_func(),或者如果必须,您也可以沿着$function_name()的路线走。可以使用这两种方法传递参数

1
2
3
4
5
$function_name = 'foobar';

$function_name(arg1, arg2);

call_user_func_array($function_name, array(arg1, arg2));

如果您调用的函数属于一个对象,您仍然可以使用其中的任何一个

1
2
3
$object->$function_name(arg1, arg2);

call_user_func_array(array($object, $function_name), array(arg1, arg2));

但是,如果您要使用$function_name()方法,那么最好测试函数的存在性,如果函数名称以任何方式是动态的。

1
2
3
4
if(method_exists($object, $function_name))
{
    $object->$function_name(arg1, arg2);
}


如果谷歌把其他人带到这里来是因为他们试图在一个类中为一个方法使用一个变量,下面是一个代码示例,它将真正起作用。以上都不适合我的情况。关键区别是$c = & new...声明中的&&$ccall_user_func中通过。

我的具体情况是,在实现某人的代码时,必须使用颜色和csscolor.php类中的两个成员方法lighten()darken()。无论出于什么原因,我想让相同的代码能够调用变亮或变暗,而不是用逻辑选择它。这可能是我顽固的结果,不只是在其他情况下使用,或者更改调用此方法的代码。

1
2
3
4
5
6
$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上php.net页面底部的读者贡献的内容后,我能够将上面的内容拼凑起来。另外,请注意,$params作为一个数组不适用于我:

1
2
3
// This doesn't work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);

上面的尝试将给出关于方法的警告,该方法需要第二个参数(百分比)。


晚了几年,但这是我现在最好的方式:

1
2
$x = (new ReflectionFunction("foo"))->getClosure();
$x();


为了完整起见,还可以使用eval():

1
2
$functionName ="foo()";
eval($functionName);

然而,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:

1
2
3
4
5
6
7
8
9
namespace greetings;

function hello()
{
    // do something
}

$myvar ="hello";
$myvar(); // interpreted as"\hello();"

怎么办?

您必须使用call_user_func()代替:

1
2
3
4
5
// if hello() is in the current namespace
call_user_func(__NAMESPACE__.'\'.$myvar);

// if hello() is in another namespace
call_user_func('
mynamespace\'.$myvar);

从PHP7开始有一些很棒的可能性。最初,正如其他人所提到的,在php5(甚至比php5更老)中,我们可以做到:

1
2
3
4
5
6
function something() {
    echo 256;
}

$foo ="something";
$foo(); // 256

这很好,但在php7中会更好。我们可以对圆括号中的(a)字符串进行任意操作,并在一次执行中将其用作函数名(假设我们已经声明了something()函数):

1
2
3
4
$bar ="some_thing";

// We use in this form: (expressions)(arguments);
(str_replace("_","", $bar))(); // 256

此外,您可以使用以下所有表单:

1
2
3
4
5
6
7
(expressions)['bar']
(expressions)->bar
(expressions)->bar()
(expressions)->$bar()
(expressions)::$bar
(expressions)::bar()
(expressions)()

例如,您可以使用匿名类和上述功能的组合:

1
2
3
echo (new class {
    public $something = 512;
})->something; // 512

此外,还可以对类实例调用以下形式的方法:

1
[objectInstance, methodName]();

例如,我们可以做到:

1
2
3
4
5
6
7
8
9
10
11
class X {
    public function object_call() {
        echo"Object Call";
    }
    public static function static_call() {
        echo"Static Call";
    }
}

[new X(),"object_call"](); // Object Call
[new X(),"static_call"](); // Static Call

从这个PHP对话中获取。


补充@chris k的答案如果你想调用一个对象的方法,你可以在闭包的帮助下使用一个变量来调用它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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"动态更改函数名。

1
2
3
4
5
6
$current_page = 'home_page';
$function = @${$current_page . '_page_versions'};
$function = function() {
    echo 'current page';
};
$function();

我从这个问题和答案中学到了什么。谢谢大家!

假设我有这些变量和函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$functionName1 ="sayHello";
$functionName2 ="sayHelloTo";
$functionName3 ="saySomethingTo";

$friend ="John";
$datas = array(
   "something"=>"how are you?",
   "to"=>"Sarah"
);

function sayHello()
{
echo"Hello!";
}

function sayHelloTo($to)
{
echo"Dear $to, hello!";
}

function saySomethingTo($something, $to)
{
echo"Dear $to, $something";
}
  • 调用不带参数的函数

    1
    2
    // Calling sayHello()
    call_user_func($functionName1);

    Hello!

  • 用1个参数调用函数

    1
    2
    // Calling sayHelloTo("John")
    call_user_func($functionName2, $friend);

    Dear John, hello!

  • 用一个或多个参数调用函数如果动态调用函数,并且每个函数的参数数目不同,那么这将非常有用。这是我一直在寻找(并解决)的案例。call_user_func_array是关键

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // You can add your arguments
    // 1. statically by hard-code,
    $arguments[0] ="how are you?"; // my $something
    $arguments[1] ="Sarah"; // my $to

    // 2. OR dynamically using foreach
    $arguments = NULL;
    foreach($datas as $data)
    {
        $arguments[] = $data;
    }

    // Calling saySomethingTo("how are you?","Sarah")
    call_user_func_array($functionName3, $arguments);

    Dear Sarah, how are you?

  • 再见!


    我想到的一个非常传统的方法是,除非您通过编写自己的超自治人工智能生成整个代码,否则很可能您希望"动态"调用的函数已经在您的代码库中定义。所以为什么不检查一下琴弦,跳一支臭名昭著的ifelse舞来召唤……你明白我的意思了。

    如。

    1
    2
    3
    4
    5
    if($functionName == 'foo'){
      foo();
    } else if($functionName == 'bar'){
      bar();
    }

    如果你不喜欢ifelse阶梯的清淡味道,甚至可以使用switch-case

    我理解有些情况下"动态调用函数"是绝对必要的(就像一些修改自身的递归逻辑)。但是,大多数日常琐碎的用例都可以被回避。

    它消除了应用程序中的许多不确定性,同时如果字符串与任何可用函数的定义都不匹配,它还为您提供了执行回退函数的机会。恕我直言。


    我不知道为什么你必须使用它,听起来一点也不好,但是如果只有少量的函数,你可以使用if/elseif构造。我不知道直接的解决办法是否可行。

    类似的东西$FO="bar";$test ="fo";回声$$测试;

    如果返回bar,您可以尝试一下,但我认为这不适用于函数