entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

Como obtener el nombre de una funcion de una clase hija a una clase madre PHP

Hola, lo que quiero hacer es algo asi:

First_class class extends Second_class
{
   function first_class_function ()
   {
   $ this-> second_class_function ();
   }
}

class Second_class
{
   function second_class_function ()
   {
   return "el nombre de la funcion que llamo a esta funcion" // en este caso deberia devolver first_class_function
   }
}

Porque lo quiero? para automatizar algo(no puedo decir mucho el aviso de confidencialidad me lo impide), desde luego puedo escribir el nombre de la funcion como un argumento, pero este no es el caso.

3 Respuestas

2votos

white Puntos75760

Una posible solución podria ser usar la clase Exception y el metodo getTrace() para obtener el seguimiento como un array.

ejemplo:

<?php

class First_class extends Second_class
{
    function first_class_function ()
    {
        return $this->second_class_function();
    }
}

class Second_class
{
    function second_class_function ()
    {
        $exception = new Exception;

        return $exception->getTrace()[1]['function'];
    }
}

$foo = new First_class();
var_dump($foo->first_class_function());

http://php.net/manual/es/class.exception.php
http://php.net/manual/es/exception.gettrace.php

vendetta comentado Abr 6, 2015

Hace un par de minutos me la resolvieron en stackoverflow XD es mas o menos lo que dices pero usando debug_backtrace sin embargo aun no estoy seguro que sea la mejor opcion yo imaginaba algo mas como static::METHOD o self::METHOD como sea aun espero haber si hay una solución mas radical. Gracias por sus respuestas veo que es un buen foro lo recomendare en mi page.

$function_name = debug_backtrace()[1]['function'];

        return $function_name;//first_class_function

1voto

dairon Puntos17090

Investiga la programación orientada a objetos y como trabajar con los métodos de los padres pero no se si un padre puede trabajar con el método de un hijo realmente eso no suena lógico para la programación orientada a objetos.
No obstante te recomiendo estos links:
Herencia en PHP
Herencia y el uso del parent
Otro ejemplo de Herencia en PHP
Herencia en PHP con ejemplo
espero que te sea de ayuda o te de una idea.
Saludos Dairon

vendetta comentado Abr 6, 2015

manejo esos conceptos a la perfección, lo que pasa es que algunos frameworks manejan algo muy similar y de ahí la necesidad, esto se puede hacer con variables staticas-acceder a atributos de los hijos- .

class Xclass extends Yclass
{
  static $variable = 10;

  function change_value()
  {
  echo $this->get_variable();//Retorna 10
  }

}

class Yclass
{
  function get_variable()
  {
  return static::$variable;
  }
}

Es un ejemplo burdo y sin gracia pero, en MVC te evita escribir código repetitivo. algo muy similar tengo en mente pero con funciones y un poco mas autonomo, mas aun no he dado con como lo hacen los frameworks o como se puede simular algo asi.

Al parecer tendre que seguir investigando.

white comentado Abr 6, 2015

podrias dar un ejemplo de que frameworks hacen esto que deseas? podrias ver el codigo fuente de este framework y ver como trabaja.

vendetta comentado Abr 6, 2015

Específicamente con una librería para codeigniter (Restfull o algo así) la sintaxis es mas o menos:

function xfunction_post()//puede ser_get_post_etc
{
//todo
}

Cuando consumes el webservice solo usas xfunction (sin el post get...) esa parte entiendo que tiene mas que ver con el htacces y el mismo core de bonfire que verifica la existencia de dicha funcion pero aun así es necesario saber el nombre de la funcion para hacer las operaciones correctas ya sean de post o get y esto solo puede hacerlo la clase madre, ya he visto el código y no encuentro como se hace.

white comentado Abr 6, 2015

Talvez te refieres a esta libreria:

https://github.com/chriskacerguis/codeigniter-restserver/blob/master/application/libraries/REST_Controller.php#L646

Esta libreria funciona obtieniendo el metodo de peticion (REQUEST_METHOD) y el metodo desde la url usando _remap

por lo que si enviamos una peticion get a esta url /profile/1/

se llama a la funcion profile_get


si lo que deseas es obtener por refleccion los metodos, campos. Informacion de una clase tambien puedes usar la clase ReflectionClass

http://php.net/manual/es/class.reflectionclass.php

vendetta comentado Abr 6, 2015

Gracias white jeje ahora que lo veo tiene sentido lo que dices, no recuerdo donde mas he visto algo semejante a lo que busco seguramente sea en JS y no tenga nada que ver XD

1voto

Leonardo-Tadei Puntos226490

Hola @vendetta,

los frameworks generalmente rutean las llamadas a las funciones o métodos correctos analizando la petición, y no en nombre de la clase llamadora, tal como sugiere @white en su comentario.

Para implementar un ruteo con la forma que proponés, la idea es que la clase que recibe el mensaje genérico no sea una subclase de la que implementa el método. De esta forma es posible analizar la clase invocada y actuar en consecuencia (además de que esta separación de clases es natural, porque tendrán distintas responsabilidades, y por tanto deben ser clases distintas).

Para saber de qué clase es un llamador se puede hacer:

<?php
class First_class extends base_class {
   function first_class_method () {
    return $this->base_class_method ();
   }
}
class base_class {
   function base_class_method () {
    //return "el nombre de la funcion que llamo a esta funcion"; // en este caso deberia devolver first_class_function
    return get_called_class();
   }
}

$o = new First_class();
var_dump( ($o->first_class_method()) );

y ahora, dependiendo de la clase (no del método) que hace la llamada, podés invocar a quien quieras.

Esto es lo que indicaría un buen diseño OO.

También se puede conocer el método llamador, pero al costo de enviarlo como parámetro. Esto no es lo que estás buscando exactamente, pero dado que cada subclase será escrita para procesar una entrada, tampoco es muy aplicable generalizarlo, porque una subclase no podrá serlo de más de una superclase.

El código quedaría así:

<?php
class First_class extends base_class {
   function first_class_method () {
    return $this->base_class_method (__METHOD__);
   }
}
class base_class {
   function base_class_method ($c) {
    //return "el nombre de la funcion que llamo a esta funcion"; // en este caso deberia devolver first_class_function
    return $c;
   }
}

$o = new First_class();
var_dump( ($o->first_class_method()) );

Si te hace falta una implemetación más genérica, la solución de diseño a este problema (el hacking con back_trace() es genial, pero no es una solución de diseño en OO) es usar Double Dispatch http://en.wikipedia.org/wiki/Double_dispatch que es el mecanismo de la POO para crear una jerarquía de clases que se encargue de resolver a quién debe llamar un método de otra clase en tiempo de ejecución.

Saludos cordiales!

vendetta comentado Abr 6, 2015

Gracias leonardo, yo necesito específicamente lo que pedí, se que en cuestión de POO estoy creando un paradigma y prácticamente "rompiendo la armonía" de la POO mas estoy seguro de que no soy el único que se ha planteado este tipo de circunstancias y ademas le ha sacado jugo a la solución.

Leonardo-Tadei comentado Abr 6, 2015

A veces por encarar mal las cosas desde el punto de vista del diseño, terminamos encontrando solucines brillantes a problemas que no hubieran existido de hacer las cosas más rigurosamente ;-)

En este caso, al no valer la pena el esfuerzo del rediseño de una pieza de código de terceros, al igual que vos yo me decanto por el hack.

Gracias por la pregunta! Fue muy estimulante

Por favor, accede o regístrate para responder a esta pregunta.

¿Conoces alguien que puede responder?
¡Comparte esta pregunta!


Otras Preguntas y Respuestas


Actividad Reciente

...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta