可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
Anyhelp would be great.
Thanks!
回答1:
$functionName()
or call_user_func($functionName)
回答2:
My favorite version is the inline version:
${\"variableName\"} = 12;
$className->{\"variableName\"};
$className->{\"methodName\"}();
StaticClass::${\"variableName\"};
StaticClass::{\"methodName\"}();
You can place variables or expressions inside the brackets too!
回答3:
Yes, it is possible:
function foo($msg) {
echo $msg.\"<br />\";
}
$var1 = \"foo\";
$var1(\"testing 1,2,3\");
Source: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
回答4:
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 so
$function_name = \'foobar\';
$function_name(arg1, arg2);
call_user_func_array($function_name, array(arg1, arg2));
If the function you are calling belongs to an object you can still use either of these
$object->$function_name(arg1, arg2);
call_user_func_array(array($object, $function_name), array(arg1, arg2));
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
if(method_exists($object, $function_name))
{
$object->$function_name(arg1, arg2);
}
回答5:
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 in call_user_func
.
My specific case is when implementing someone\'s code having to do with colors and two member methods lighten()
and darken()
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.
$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);
Note that trying anything with $c->{...}
didn\'t work. Upon perusing the reader-contributed content at the bottom of php.net\'s page on call_user_func
, I was able to piece together the above. Also, note that $params
as an array didn\'t work for me:
// This doesn\'t work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);
This above attempt would give a warning about the method expecting a 2nd argument (percent).
回答6:
A few years late, but this is the best manner now imho:
$x = (new ReflectionFunction(\"foo\"))->getClosure();
$x();
回答7:
For the sake of completeness, you can also use eval():
$functionName = \"foo()\";
eval($functionName);
However, call_user_func()
is the proper way.
回答8:
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:
namespace greetings;
function hello()
{
// do something
}
$myvar = \"hello\";
$myvar(); // interpreted as \"\\hello();\"
What to do?
You have to use call_user_func()
instead:
// if hello() is in the current namespace
call_user_func(__NAMESPACE__.\'\\\\\'.$myvar);
// if hello() is in another namespace
call_user_func(\'mynamespace\\\\\'.$myvar);
回答9:
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:
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\"
I posted another example here
回答10:
There are some awesome possibilities as of PHP7. Initially, as others mentioned, in PHP5 (and even older than PHP5) we could do:
function something() {
echo 256;
}
$foo = \"something\";
$foo(); // 256
This is good, but it got better in PHP7. We can make arbitrary operations on (a) string(s) in parentheses and use it as the function name in just one go (consider we have declared something() function):
$bar = \"some_thing\";
// We use in this form: (expressions)(arguments);
(str_replace(\"_\", \"\", $bar))(); // 256
Furthermore, you could use all of the following form:
(expressions)[\'bar\']
(expressions)->bar
(expressions)->bar()
(expressions)->$bar()
(expressions)::$bar
(expressions)::bar()
(expressions)()
For example, you could use a combination of anonymous classes and the feature above:
echo (new class {
public $something = 512;
})->something; // 512
Also, you can call a method on a class instance in the form of:
[objectInstance, methodName]();
As an example, we could do:
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
Taken from this PHP talk.
回答11:
Use the call_user_func function.
回答12:
Following code can help to write dynamic function in PHP.
now the function name can be dynamically change by variable \'$current_page\'.
$current_page = \'home_page\';
$function = @${$current_page . \'_page_versions\'};
$function = function() {
echo \'current page\';
};
$function();
回答13:
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.
if($functionName == \'foo\'){
foo();
} else if($functionName == \'bar\'){
bar();
}
Even switch-case
can be used if you don\'t like the bland taste of ifelse
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.
回答14:
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