8
votes

Méthode_existes dans la classe parente PHP

J'essaie d'utiliser la méthode de la fonction PHP_exists, mais je dois vérifier si la méthode existe dans la classe mère d'un objet.

SO: P>

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


2 commentaires

Je crois que is_callable () nécessite une instance de classe comme premier index de tableau, pas un nom de classe. c'est à dire. Si (IS_CALLABLE (TRAY ($ MyChild, 'myfunction')))) - Bien que pour cela fonctionne, votre classe enfant doit étendre le parent (comme mentionné ci-dessous).


Avez-vous besoin de savoir si a) exactement la classe des parents implémente une méthode B) Toute 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) que vous pouvez appeler une méthode spécifique sur un objet?


6 Réponses :


11
votes

La classe enfant doit étendre le parent dans ce cas

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


4 commentaires

J'ai oublié d'ajouter la partie étendue, dans mon enfant, l'enfant étendue parent. C'est en fait une classe modèle de base de la doctrine, mais sur une enquête plus forte, je ne pense pas que ce que j'essaie de faire fonctionnera, car les fonctions dans les classes de modèle de base de la doctrine semblent fonctionner avec la surcharge / l'interception, car il n'y a pas de déclarations de fonction visibles


@Sserg Si vous avez étend le parent dans votre code actuel, votre première expression si (méthod_exists ($ mychild, "myfunction")) serait vrai. (NB: J'ai ajouté la parenthèse de fermeture)


@Serg: Vous devriez peut-être ajouter un exemple plus concret à votre question et expliquer en détail ce que vous essayez réellement de réaliser.


Merci à tout le monde, j'ai fini par utiliser IS_CALLABLE et cela fonctionne maintenant comme vous le souhaitez.



1
votes

robertpitt est correct en ce que la classe enfant code> n'est pas une classe enfant, sauf si elle étend la classe parent code>. Mais à partir de votre extrait de code d'origine, vous devriez être vrai:

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


0 commentaires

5
votes

Si vous voulez savoir spécifiquement si cela existe dans le parent, et non seul dans votre propre classe: xxx


0 commentaires

9
votes

Vous devez utiliser PHP's Réflexion API:

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'


3 commentaires

L'API de réflexion fonctionne-t-elle également avec des objets qui utilisent la surcharge / interception?


AFAIK Il inspecte de manière dynamique (à l'exécution) inspecte des objets / classes, de sorte que ce serait oui.


Non, il ne serait pas capable de attraper cela un __ appel () (bien qu'il soit facile de tester l'existence de __ appel () ). Ex: Classe A {Fonction __Call ($ Func, $ args) {}} $ R = NouvelleClass ('A'); var_dump ($ R-> hasmethod'thisrandomfuncti oneworks ')); sortira Faux, bien que la fonction puisse être appelée.



2
votes

ne serait pas méthodé_exists et get_parent_class combiné fonctionnent également si c'est fait dans la classe enfant?

par exemple xxx


0 commentaires

1
votes

L'exemple: Si (méthod_existes («parent», «myfunction») ne fonctionne pas dans PHP 5.3.5 Si vous souhaitez rechercher un constructeur parent.

mais cela a fonctionné pour moi: xxx

Il appelle le constructeur parent uniquement si le Il existe dans la classe des parents


1 commentaires

Bien fait, cela fonctionne sous PHP 8.0.3 aussi!