parent :: parent в PHP - PullRequest
       30

parent :: parent в PHP

39 голосов
/ 21 ноября 2011

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

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, они являются частью фреймворка ...)

Ответы [ 9 ]

55 голосов
/ 21 ноября 2011

Простое решение. Используйте корневой объект myclass напрямую:

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

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

22 голосов
/ 21 ноября 2011

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

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

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

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

4 голосов
/ 21 ноября 2011

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

class myclass3{
myclass2 obj2;
public function test() { return $obj2->callParentTest() . '-level3';}
}
3 голосов
/ 21 ноября 2011

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

2 голосов
/ 21 ноября 2011

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

Вы попробуете "parent::parent::parent::parent", когда у вас есть class5 ??

Я думаю, вы можете добавить параметр 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"
2 голосов
/ 21 ноября 2011

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

1 голос
/ 07 апреля 2016

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

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();
    }
}
1 голос
/ 14 августа 2013

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

1 голос
/ 21 ноября 2011

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

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