valores - Cómo llamar a la función PHP desde una cadena almacenada en una variable
pasar variable de una funcion a otra php (14)
Nombres de funciones dinámicas y espacios de nombres
Solo para agregar un punto sobre los nombres de funciones dinámicas cuando se usan espacios de nombres.
Si está usando espacios de nombres, lo siguiente no funcionará excepto si su función está en el espacio de nombres global:
namespace greetings;
function hello()
{
// do something
}
$myvar = "hello";
$myvar(); // interpreted as "/hello();"
¿Qué hacer?
Tienes que usar call_user_func()
lugar:
// if hello() is in the current namespace
call_user_func(__NAMESPACE__.''//'.$myvar);
// if hello() is in another namespace
call_user_func(''mynamespace//'.$myvar);
Necesito poder llamar a una función, pero el nombre de la función se almacena en una variable, ¿es esto posible? p.ej:
function foo () { //code here } function bar () { //code here } $functionName = "foo"; // i need to call the function based on what is $functionName
Cualquier ayuda sería genial.
¡Gracias!
Como ya se mencionó, hay algunas formas de lograrlo, ya que posiblemente el método más seguro sea call_user_func()
o, si debe hacerlo, también puede seguir la ruta de $function_name()
. Es posible pasar argumentos utilizando estos dos métodos como tal
$function_name = ''foobar'';
$function_name(arg1, arg2);
call_user_func_array($function_name, array(arg1, arg2));
Si la función que está llamando pertenece a un objeto, aún puede utilizar cualquiera de estos
$object->$function_name(arg1, arg2);
call_user_func_array(array($object, $function_name), array(arg1, arg2));
Sin embargo, si va a utilizar el método $function_name()
, puede ser una buena idea probar la existencia de la función si el nombre es dinámico.
if(method_exists($object, $function_name))
{
$object->$function_name(arg1, arg2);
}
Complementando la respuesta de @Chris K si desea llamar al método de un objeto, puede llamarlo usando una sola variable con la ayuda de un cierre:
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"
Publiqué otro ejemplo here
El siguiente código puede ayudar a escribir una función dinámica en PHP. ahora el nombre de la función se puede cambiar dinámicamente por la variable ''$ current_page''.
function something() {
echo 256;
}
$foo = "something";
$foo(); // 256
En aras de la exhaustividad, también puede utilizar eval() :
$functionName = "foo()";
eval($functionName);
Sin embargo, call_user_func($functionName) es la forma correcta.
En caso de que otra persona sea traída por Google porque intentaba usar una variable para un método dentro de una clase, a continuación se muestra un ejemplo de código que realmente funcionará. Nada de lo anterior funcionó para mi situación. La diferencia clave es que &
en la declaración de $c = & new...
y &$c
se pasa en call_user_func
.
Mi caso específico es cuando se implementa el código de alguien relacionado con los colores y los métodos de dos miembros lighten()
y darken()
de la clase csscolor.php. Por la razón que sea, quería que el mismo código pudiera llamar a aclarar u oscurecer en lugar de seleccionarlo con lógica. Esto puede ser el resultado de mi terquedad para no solo usar if-else o para cambiar el código que llama a este método.
$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);
Tenga en cuenta que intentar algo con $c->{...}
no funcionó. Al leer el contenido contribuido por el lector en la parte inferior de la página de php.net en call_user_func
, pude juntar lo anterior. Además, tenga en cuenta que $params
como una matriz no funcionó para mí:
// This doesn''t work:
$params=Array($color,$percent);
$rtn=call_user_func( array(&$c,$lightdark),$params);
Este intento anterior daría una advertencia sobre el método que espera un segundo argumento (porcentaje).
Hay algunas posibilidades impresionantes a partir de PHP7. Inicialmente, como han mencionado otros, en PHP5 (e incluso más antiguo que PHP5) podríamos hacer:
$bar = "some_thing";
// We use in this form: (expressions)(arguments);
(str_replace("_", "", $bar))(); // 256
Esto es bueno, pero mejoró en PHP7. Podemos realizar operaciones arbitrarias en (a) cadena (s) entre paréntesis y usarlo como el nombre de la función de una sola vez (considere que hemos declarado la función de algo ()):
(expressions)[''bar'']
(expressions)->bar
(expressions)->bar()
(expressions)::$bar
(expressions)::bar()
(expressions)()
Además, puede utilizar todo el siguiente formulario:
echo (new class {
public $something = 512;
})->something; // 512
Por ejemplo, podría usar una combinación de clases anónimas y la característica anterior:
[objectInstance, methodName]();
Además, puede llamar a un método en una instancia de clase en la forma de:
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
Como ejemplo, podríamos hacer:
$current_page = ''home_page'';
$function = @${$current_page . ''_page_versions''};
$function = function() {
echo ''current page'';
};
$function();
Tomado de esta charla de PHP .
Mi versión favorita es la versión en línea:
${"variableName"} = 12;
$className->{"variableName"};
$className->{"methodName"}();
StaticClass::${"variableName"};
StaticClass::{"methodName"}();
¡También puedes colocar variables o expresiones dentro de los paréntesis!
No sé por qué tienes que usar eso, no me suena tan bien, pero si solo hay una pequeña cantidad de funciones, podrías usar una construcción if / elseif. No sé si una solución directa es posible.
algo como $ foo = "bar"; $ test = "foo"; prueba de eco $$;
Debería volver a la barra, puedes probar, pero no creo que esto funcione para las funciones
Sí, es posible:
function foo($msg) {
echo $msg."<br />";
}
$var1 = "foo";
$var1("testing 1,2,3");
Fuente: http://www.onlamp.com/pub/a/php/2001/05/17/php_foundations.html?page=2
Un enfoque poco convencional, que me vino a la mente, es que, a menos que esté generando todo el código a través de alguna IA súper ultra autónoma que se escribe , hay muchas posibilidades de que las funciones a las que desea llamar "dinámicamente" ya estén definidas en su código. base. Entonces, ¿por qué no solo compruebas la cuerda y haces la infame danza ifelse
para convocar al ... ya entiendes mi punto?
p.ej.
if($functionName == ''foo''){
foo();
} else if($functionName == ''bar''){
bar();
}
Incluso se puede usar una switch-case
si no le gusta el sabor suave de la escalera ifelse
.
Entiendo que hay casos en los que " llamar a la función dinámicamente " sería una necesidad absoluta ( como una lógica recursiva que se modifica ). Pero la mayoría de los casos de uso triviales cotidianos solo pueden ser esquivados.
Elimina una gran cantidad de incertidumbre de su aplicación, mientras le da la oportunidad de ejecutar una función de respaldo si la cadena no coincide con ninguna de las definiciones de funciones disponibles. EN MI HUMILDE OPINIÓN.
Unos pocos años tarde, pero esta es la mejor manera ahora imho:
$x = (new ReflectionFunction("foo"))->getClosure();
$x();
Utilice la función call_user_func.