2010-07-22 5 views
5

J'essaie d'utiliser la fonction php method_exists, mais j'ai besoin de vérifier si la méthode existe dans la classe parente d'un objet.method_exists dans la classe parente php

donc:

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')) 
{ 
    /* ... */ 
} 

Mais aucune de ces travaillent. Je ne suis pas sûr de ce qu'il faut essayer ensuite.

Merci pour toute aide!

+0

Je crois que 'is_callable()' nécessite une instance de classe comme premier index de tableau, pas un nom de classe. c'est à dire. 'if (is_callable (array ($ myChild, 'myFunction'))) - bien que pour que cela fonctionne, votre classe' Child' doit étendre le 'Parent' (comme mentionné ci-dessous). – MrWhite

+0

Avez-vous besoin de savoir si a) exactement la classe parente implémente une méthode b) tout ancêtre d'une classe donnée implémente une méthode c) un objet d'une classe dérivée "a" une méthode spécifique d) vous pouvez appeler une méthode spécifique sur un objet? – VolkerK

Répondre

7

enfant classe doit étendre le parent dans ce cas

class Parent 
{ 
    public function hello() 
    { 

    } 
} 

class Child extends Parent 
{ 

} 

$child = new Child(); 

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

Mise à jour Cela aurait le même effet que method_exists je crois.

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(); 
} 

Juste mis à jour de poste de Wrikken

+0

J'ai oublié d'ajouter la partie extends, dans mon projet Child étend Parent. Il s'agit en fait d'une classe Doctrine Base Model, mais je ne pense pas que ce que j'essaie de faire fonctionnera, car les fonctions des classes du modèle Doctrine Base semblent fonctionner avec surcharge/interception car aucune déclaration de fonction n'est visible – Serg

+0

@Serg Si vous avez 'extends Parent' dans votre code actuel, alors votre première expression' if (method_exists ($ myChild, 'myFunction')) 'serait vraie. (NB: j'ai ajouté la parenthèse fermante) – MrWhite

+0

@Serg: Peut-être que vous devriez ajouter un exemple plus concret à votre question et expliquer en détail ce que vous essayez réellement d'accomplir. – VolkerK

1

RobertPitt est correct en ce que la classe Child n'est pas une classe enfant à moins qu'il étend la classe Parent. Mais à partir de l'extrait de code d'origine, ce qui suit devrait être vrai:

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

Notez le « parent » est entre guillemets, vous l'aviez sans guillemets. Passer le nom de la classe comme une chaîne.

4

Si vous voulez savoir précisément si elle existe dans le parent, et non seulement dans votre propre classe:

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

Vous devez utiliser l'API PHP :

class Parend 
{ 
    public function myFunction() 
    { 

    } 
} 

class Child extends Parend{} 

$c = new Child(); 


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

Et si vous voulez savoir dans quelle classe (parent) vit la méthode:

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

L'API de réflexion fonctionne-t-elle également avec les objets qui utilisent une surcharge/interception? – kiamlaluno

+0

AFAIK dynamiquement (à l'exécution) inspecte les objets/classes, ce serait oui. –

+0

Non, il ne serait pas capable d'attraper une fonction '__call()' (bien qu'il soit facile de tester l'existence de '__call()'). Ex: 'class A {fonction __call ($ func, $ args) {}} $ r = nouvelle ReflectionClass ('A'); var_dump ($ r-> hasMethod'thisRandomFunctionWorks '))' renvoie faux, bien que la fonction puisse être appelé. – Wrikken

1

Est-ce que method_exists et get_parent_class combinés ne fonctionneraient pas non plus dans la classe enfant?

Par exemple

class Parent 
{ 

} 

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

Le excample. si (method_exists ('Parent', 'myFunction') ne fonctionne pas en PHP 5.3.5 si vous voulez vérifier pour un constructeur parent

Mais cela a fonctionné pour moi:

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

il appelle le constructeur parent que si l'on existe dans la classe mère

Questions connexes