PHP Llame a un método de instancia con call_user_func dentro de la misma clase

3 minutos de lectura

estoy tratando de usar call_user_func para llamar a un método desde otro método del mismo objeto, por ejemplo

class MyClass
{
    public function __construct()
    {
        $this->foo('bar');
    }
    public function foo($method)
    {
        return call_user_func(array($this, $method), 'Hello World');
    }

    public function bar($message)
    {
        echo $message;
    }
}

new MyClass; Debería devolver ‘Hello World’…

¿Alguien sabe la forma correcta de lograr esto?

¡Muchas gracias!

  • Se ve bien. ¿Qué no funciona?

    – Peka

    26 de noviembre de 2010 a las 19:39

  • Devolver tiene un significado definido en PHP y si se refiere a otra cosa, debe aclararlo.

    – Gordon

    26 de noviembre de 2010 a las 20:04

avatar de usuario
pablo dixon

El código que publicaste debería funcionar bien. Una alternativa sería usar “funciones variables” como esto:

public function foo($method)
{
     //safety first - you might not need this if the $method
     //parameter is tightly controlled....
     if (method_exists($this, $method))
     {
         return $this->$method('Hello World');
     }
     else
     {
         //oh dear - handle this situation in whatever way
         //is appropriate
         return null;
     }
}

  • esto también es más rápido que usar call_user_func aunque he visto a muchos fruncir el ceño al hacerlo de esta manera… yo no soy uno de esos 🙂

    – prodigitalson

    26 de noviembre de 2010 a las 19:43


  • este es uno de esos modismos de ‘un gran poder conlleva una gran responsabilidad’… úsalo para el bien, no para el mal 🙂

    –Paul Dixon

    26 de noviembre de 2010 a las 19:45

  • Desaprobaría un poco esto porque arroja un error fatal si el método no existe, pero probablemente sea seguro asumir que la verificación se realiza en otro lugar

    – Peka

    26 de noviembre de 2010 a las 19:45


  • @pekka: bueno, para mí esto es siempre envuelto en cheque para method_exists($obj, $method) o is_callable dependiendo del uso.

    – prodigitalson

    26 de noviembre de 2010 a las 19:47


  • Gracias, no había pensado en ese enfoque 🙂

    – Fred

    26 de noviembre de 2010 a las 20:23

Esto funciona para mí:

<?php
class MyClass
{
    public function __construct()
    {
        $this->foo('bar');
    }
    public function foo($method)
    {
        return call_user_func(array($this, $method), 'Hello World');
    }

    public function bar($message)
    {
        echo $message;
    }
}

$mc = new MyClass();
?>

Esto se imprime:

wraith:Downloads mwilliamson$ php userfunc_test.php 
    Hello World

  • Gracias, lo intentaré de nuevo, ¡debo haber tenido un error cuando lo probé originalmente!

    – Fred

    26 de noviembre de 2010 a las 20:23

  • Debería ser la mejor respuesta, gracias!

    –David Vander Elst

    22 de diciembre de 2021 a las 10:42

avatar de usuario
gordon

nuevo Mi Clase; Debería devolver ‘Hello World’…

Un constructor no devuelve nada.

  • Creo que “retorno” se entiende en un sentido muy amplio aquí (léase: se refiere al echo). Aún así, tienes razón

    – Peka

    26 de noviembre de 2010 a las 19:43


  • @Pekka y quienquiera que esté de acuerdo contigo. Si el OP significaba return significar echo, entonces, ¿por qué el OP hace la pregunta? El código lo hace echo cuando se invoca el ctor.

    – Gordon

    26 de noviembre de 2010 a las 19:48

  • @Gordon the OP es 1) devolver los resultados de una función que no devuelve nada, y 2) no intentar devolver nada en el constructor. Para mí, esa es una evidencia abrumadora de que realmente no quiso decir “regresar” 🙂

    – Peka

    26 de noviembre de 2010 a las 19:51


  • @gordon: Estuve de acuerdo con Pekka. Y aunque su interpretación es válida desde el punto que menciona, diría que la de Pekka también lo es, ya que el OP ni siquiera intenta un return $this->foo('bar') en su constructor 🙂

    – prodigitalson

    26 de noviembre de 2010 a las 19:53

  • @Pekka bar no devuelve nada, pero eso no significa que otros métodos no devuelvan algo. foo solo está invocando métodos arbitrarios, por lo que es razonable tener un retorno allí.

    – Gordon

    26 de noviembre de 2010 a las 19:54

¿Ha sido útil esta solución?