Подтвердить что ты не робот

Parent:: parent в PHP

Я ищу способ доступа к родительской, родительской функции класса без вызова родителя... Хм, это звучит немного странно, поэтому я приведу пример:

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"

Я хотел бы отобразить "уровень 1-уровень 3", а затем сделать что-то вроде этого:

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

У вас есть идея, как я могу это сделать? (Я не могу редактировать myclass и myclass2, они являются частью структуры...)

4b9b3361

Ответ 1

Простое решение. Используйте непосредственно объект myclass root:

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

Если вам нужен более общий подход, посмотрите outis answer.

Ответ 2

Вы можете сделать это, используя 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'; 
    }
}

Или вы можете использовать reflection:

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

Однако, это может быть не очень хорошая идея, в зависимости от того, чего вы пытаетесь достичь.

Ответ 3

Возможно, вы можете просто добавить myclass2 в качестве объекта-члена в myclass3 и попытаться выполнить код как:

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

Ответ 4

Нет, это невозможно. К сожалению, нет возможности напрямую ссылаться на исходный класс, только на него self или на него parent.

Ответ 5

Вы не можете связать родителей, вместо этого создайте какой-то метод GetParent() в родительских классах, который просто возвращает $this;

Ответ 6

если вы хотите использовать тестовую функцию непосредственно в классе1, вы должны перейти от класса 1. Пожалуйста, ищите о полиморфизме.

попробуйте "parent::parent::parent::parent", если у вас есть класс5??

Я думаю, вы можете добавить параметр level для тестирования метода. и сначала проверьте его.

<?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"

Ответ 7

Для получения корневого объекта нет оператора. Я бы сделал что-то вроде этого:

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"

Ответ 8

В некоторых ситуациях, возможно, вы можете полностью переопределить корневой метод. Я имею в виду, вместо вызова родительского родительского кода вы можете скопировать родительский метод родительского метода и добавить свои.

Ответ 9

мой подход: если у вас есть код:

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

и вы хотите в class C вызвать метод из class A (но не class B) реорганизовать его в код:

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