Solución: use PHP7
Nota: Para una versión resumida, vea TL; DR al final de la respuesta.
Viejos métodos
Actualización : se ha eliminado uno de los métodos antiguos explicados aquí. Consulte otras respuestas para obtener una explicación sobre otros métodos, no está cubierto aquí. Por cierto, si esta respuesta no te ayuda, deberías volver a actualizar tus cosas. La compatibilidad con PHP 5.6 finalizó en enero de 2019 (ahora incluso PHP 7.0 y 7.1 no son compatibles). Consulte las versiones compatibles para obtener más información.
Como otros mencionaron, en PHP5 (y también en versiones más nuevas como PHP7) podríamos usar variables como nombres de funciones, usar call_user_func()
y call_user_func_array()
(que, personalmente, odio esas funciones), etc.
Nuevos métodos
A partir de PHP7, hay nuevas formas introducidas:
Nota: Todo entre <something>
paréntesis significa una o más expresiones para formar algo, por ejemplo <function_name>
, expresiones que forman el nombre de una función.
Llamada de función dinámica: nombre de la función sobre la marcha
Podemos usar una o más expresiones entre paréntesis como el nombre de la función de una sola vez, en forma de:
(<function_name>)(arguments);
Por ejemplo:
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))()();
Nota: Aunque eliminar los paréntesis str_replace()
no es un error, poner paréntesis hace que el código sea más legible. Sin embargo, a veces no puede hacerlo, por ejemplo, mientras usa el .
operador. Para ser coherente, te recomiendo poner los paréntesis siempre.
Llamada de método dinámico: nombre del método sobre la marcha
Al igual que las llamadas a funciones dinámicas, podemos hacer lo mismo con las llamadas a métodos, rodeadas de llaves en lugar de paréntesis (para formas adicionales, navegue a TL; sección DR):
$object->{<method_name>}(arguments);
$object::{<method_name>}(arguments);
Véalo en un ejemplo:
class Foo
{
public function another(): string
{
return "something";
}
}
$bar = "another thing";
(new Something())->{explode(" ", $bar)[0]}(); // something
Llamada de método dinámico: la sintaxis de matriz
Una forma más elegante agregada en PHP7 es la siguiente:
[<object>, <method_name>](arguments);
[<class_name>, <method_name>](arguments); // Static calls only
Como ejemplo:
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
Nota: El beneficio de usar este método sobre el anterior es que no le importa el tipo de llamada (es decir, si es estático o no).
Ejemplo adicional: uso de clases anónimas
Para complicar un poco las cosas, puede usar una combinación de clases anónimas y las características anteriores:
$bar = "SomeThing";
echo (new class {
public function something()
{
return 512;
}
})->{strtolower($bar)}(); // 512
TL; DR (Conclusión)
En general, en PHP7, es posible usar los siguientes formularios:
// Everything inside `<something>` brackets means one or more expressions
// to form something
// Dynamic function call
(<function_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)
Basado principalmente en esta charla PHP .