web-dev-qa-db-fra.com

parent :: parent dans PHP

Je cherche un moyen d'accéder au parent, la fonction parent d'une classe sans appeler le parent ... Hmmm, ça sonne une explication un peu bizarre donc je vais donner un exemple:

class myclass
{
  public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
  public function test() { return parent::test() . '-level 2'; }
}
class myclass3 extends myclass2
{
  public function test() { return parent::test() . '-level 3'; }
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 2-level 3"

Je voudrais afficher "niveau 1-niveau 3" puis faire quelque chose comme ça:

class myclass3 extends myclass2
{
  public function test() { return parent::parent::test() . '-level 3'; }
}

Avez-vous une idée de comment je peux faire ça? (Je ne suis pas autorisé à éditer myclass et myclass2, ils font partie d'un framework ...)

40
Alexandre

Solution simple. Utilisez directement l'objet racine myclass:

class myclass3 extends myclass2
{
  public function test() { return myclass::test() . '-level 3'; }
}

Si vous avez besoin d'une approche plus générale, consultez outis answer .

56
PiTheNumber

Vous pouvez le faire en utilisant get_parent_class

function get_grandparent_class($thing) {
    if (is_object($thing)) {
        $thing = get_class($thing);
    }
    return get_parent_class(get_parent_class($thing));
}

class myclass3 extends myclass2 {
    public function test() {
      $grandparent = get_grandparent_class($this);
      return $grandparent::test() . '-level 3'; 
    }
}

Ou vous pouvez utiliser réflexion :

function get_grandparent_class($thing) {
    if (is_object($thing)) {
        $thing = get_class($thing);
    }
    $class = new ReflectionClass($thing);
    return $class->getParentClass()->getParentClass()->getName();
}

Cependant, cela peut ne pas être une bonne idée, selon ce que vous essayez de réaliser.

22
outis

Peut-être que vous pouvez simplement ajouter myclass2 en tant qu'objet membre dans myclass3 et essayer de coder comme:

class myclass3{
myclass2 obj2;
public function test() { return $obj2->callParentTest() . '-level3';}
}
4
LostMohican

Non, ce n'est pas possible. Malheureusement, il n'est pas possible de se référer directement à la classe d'origine, seulement à son self ou à son parent.

3
Wesley van Opdorp

si vous souhaitez utiliser la fonction de test directement sur la classe 1, vous devez étendre la classe 1. Veuillez rechercher le polimorphisme.

vas-tu essayer "parent::parent::parent::parent "quand vous avez class5 ??

Je pense que vous pouvez ajouter un paramètre level à la méthode de test. et vérifiez-le d'abord.

<?php
    class myclass
    {
        public function test($level) 
        { 
            return 'level 1'; 
        }
    }
    class myclass2 extends myclass
    {
        public function test($level) 
        { 

            return $level >= 2 ? parent::test($level) . '-level 2' : parent::test($level); 
        }
    }
    class myclass3 extends myclass2
    {
        public function test() 
        { 
            return parent::test(1) . '-level 3';
        }
    }
    $example = new myclass3();
    echo $example->test(); // should display "level 1-level 3"

Vous ne pouvez pas enchaîner les parents, mais créez une sorte de méthode GetParent () dans vos classes parent qui renvoie simplement $ this;

2
Eric Herlitz

mon approche: si vous avez le code:

class A {
    protected function method () {
        var_dump('A -> method');
    }
}

class B extends A {
    protected function method () {
        var_dump('B -> method');
    }
}

class C extends B {
    protected function method () {
        var_dump('C -> method');
    }
}

et vous voulez dans class C appeler méthode à partir de class A (mais non class B) refactoriser le code:

<?php

class A {
    protected function method () {
        $this->methodA();
    }

    protected function methodA () {
        var_dump('A -> method');
    }
}

class B extends A {
    protected function method () {
        var_dump('B -> method');
    }
}

class C extends B {
    protected function method () {
        $this->methodA();
    }
}
1
W92

Dans certaines situations, vous pouvez probablement remplacer entièrement la méthode de la racine. Je veux dire, au lieu d'appeler celui du parent du parent, vous pouvez copier le code de méthode du parent du parent et ajouter le vôtre.

1
Luca Reghellin

Il n'y a aucun opérateur pour obtenir l'objet racine. Je ferais quelque chose comme ça:

class myclass
{
  public function getRoot() { return __CLASS__; }
  public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
  public function getRoot() { return parent::getRoot(); }
}
class myclass3 extends myclass2
{
  public function getRoot() { return parent::getRoot(); }
  public function test() {
    $grandparent = self::getRoot();
    return $grandparent::test() . '-level 3';
  }
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 2-level 3"
1
PiTheNumber