2010-07-22 12 views
5

Estoy tratando de usar la función php method_exists, pero necesito verificar si el método existe en la clase padre de un objeto.method_exists en la clase padre php

manera:

class Parent 
{ 
    public function myFunction() 
    { 
     /* ... */ 
    } 
} 

class Child extends Parent 
{ 
    /* ... */ 
} 

$myChild = new Child(); 

if (method_exists($myChild, 'myFunction')) 
{ 
    /* ... */ 
} 

if (method_exists(Parent, 'myFunction')) 
{ 
    /* ... */ 
} 

if (is_callable(array('Parent', 'myFunction')) 
{ 
    /* ... */ 
} 

Pero ninguna de las anteriores están trabajando. No estoy seguro de qué probar después.

¡Gracias por cualquier ayuda!

+0

Creo que 'is_callable()' requiere una instancia de clase como primer índice de matriz, no como nombre de clase. es decir. 'if (is_callable (array ($ myChild, 'myFunction')))) - aunque para que esto funcione, su clase' Child' necesita extender 'Parent' (como se menciona a continuación). – MrWhite

+0

¿Necesita saber si a) exactamente la clase padre implementa un método b) cualquier antecesor de una clase determinada implementa un método c) un objeto de una clase derivada "tiene" un método específico d) puede llamar a un método específico en ¿un objeto? – VolkerK

Respuesta

7

niño Clase debe extenderse a los padres en ese caso

class Parent 
{ 
    public function hello() 
    { 

    } 
} 

class Child extends Parent 
{ 

} 

$child = new Child(); 

if(method_exists($child,"hello")) 
{ 
    $child->hello(); 
} 

actualización Esto tendría el mismo efecto que method_exists creo.

function parent_method_exists($object,$method) 
{ 
    foreach(class_parents($object) as $parent) 
    { 
     if(method_exists($parent,$method)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

if(method_exists($child,"hello") || parent_method_exists($object,"hello")) 
{ 
    $child->hello(); 
} 

acaba de actualizar desde el post Wrikken 's

+0

Olvidé agregar la parte de extensiones, en mi proyecto Child extiende Parent. En realidad es una clase Doctrine Base Model, pero en una investigación posterior no creo que lo que intento hacer funcionará, ya que las funciones en las clases del modelo Doctrine Base parecen funcionar con sobrecarga/intercepción ya que no hay declaraciones de funciones visibles – Serg

+0

@Serg Si tiene 'extends Parent' en su código actual, entonces su primera expresión' if (method_exists ($ myChild, 'myFunction')) 'sería verdadera. (NB: Agregué el paréntesis de cierre) – MrWhite

+0

@Serg: Tal vez debería agregar un ejemplo más concreto a su pregunta y explicar en detalle lo que realmente está tratando de lograr. – VolkerK

1

RobertPitt es correcto en que la clase Child no es una clase hija a menos que extiende la clase Parent. Pero desde el fragmento de código original, lo siguiente debe ser cierto:

if (method_exists('Parent', 'myFunction') 
{ 
    // True 
} 

Nota del 'Padre' está entre comillas, que lo tenía sin comillas. Pasar el nombre de la clase como una cadena.

4

Si desea saber específicamente si existe en los padres, y no única en su propia clase:

foreach(class_parents($this) as $parent){ 
    if(method_exists($parent,$method){ 
     //do something, for instance: 
     parent::$method(); 
     break; 
    } 
} 
9

Debe utilizar API de PHP:

class Parend 
{ 
    public function myFunction() 
    { 

    } 
} 

class Child extends Parend{} 

$c = new Child(); 


$rc = new ReflectionClass($c); 
var_dump($rc->hasMethod('myFunction')); // true 

Y si desea saber en que clase (principal) el método vive:

class Child2 extends Child{} 

$c = new Child2(); 
$rc = new ReflectionClass($c); 

while($rc->getParentClass()) 
{ 
    $parent = $rc->getParentClass()->name; 
    $rc = new ReflectionClass($parent); 
} 
var_dump($parent); // 'Parend' 
+0

¿La API de reflexión funciona también con objetos que usan sobrecarga/intercepción? – kiamlaluno

+0

AFAIK dinámicamente (en tiempo de ejecución) inspecciona objetos/clases, por lo que sería sí. –

+0

No, no podría detectar esa función '__call()' (aunque sería fácil probar la existencia de '__call()'). Ej: 'clase A {función __call ($ func, $ args) {}} $ r = new ReflectionClass ('A'); var_dump ($ r-> hasMethod'thisRandomFunctionWorks '));' salidas falsas, aunque la función puede ser llamado. – Wrikken

1

¿No funcionarían method_exists y get_parent_class también funcionan si se hace dentro de la clase secundaria?

Por ejemplo

class Parent 
{ 

} 

class Child extends Parent 
{ 
    public function getConfig() 
    { 
    $hello = (method_exists(get_parent_class($this), 'getConfig')) ? parent::getConfig() : array(); 
    } 
} 
0

El excample:. si (method_exists ('Padre', 'myFunction') no funciona en PHP 5.3.5 si lo desea para comprobar si hay un constructor padre

Pero esto funcionó para mí:

class Child extends Parent { 
    function __construct($argument) { 
    if(method_exists(get_parent_class(),"__construct")) parent::__construct($argument) 
    } 
} 

se llama al constructor de padres sólo si el que existe en la clase padre

Cuestiones relacionadas