如何从继承的方法中调用PHP父方法? [英] How do I call PHP parent methods from within an inherited method?

查看:101
本文介绍了如何从继承的方法中调用PHP父方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在PHP中,我试图从继承自对象父类的方法引用对象父类中定义的方法。这是代码:

In PHP, I'm trying to reference a method defined in an object's parent class, from a method inherited from the object's parent class. Here's the code:

class base_class {
  function do_something() {
    print "base_class::do_something()\n";
  }
  function inherit_this() {
    parent::do_something();
  }
}
class middle_class extends base_class {
  function do_something() {
    print "middle_class::do_something()\n";
  }
}
class top_class extends middle_class {
  function do_something() {
    print "top_class::do_something()\n";
    $this->inherit_this();
  }
}

$obj = new top_class;
$obj->do_something();

问题是inherit_this()中的parent :: do_something()试图找到父类base_class,而不是对象的实际类的父级,上面的示例引发错误。有什么我可以写的而不是parent :: do_something()会调用middle_class :: do_something(),这甚至可以在扩展(比如说)top_class的类中工作吗?

The problem is that parent::do_something() in inherit_this() tries to find the parent class of base_class, not the parent of the object's actual class, and the example above throws an error. Is there something I can write instead of parent::do_something() that would call middle_class::do_something(), and that would still work even in classes that extend (say) top_class?

推荐答案

我首先要对grrbrr404说谢谢。他给了我一些想法,让我开始朝着正确的方向前进。

I'll start by saying "Thank you" to grrbrr404. He gave me some ideas and got me started in the right direction.

我最终确定的解决方案如下:

The solution I finally settled on was the following:

function inherit_this() {
  $bt = debug_backtrace();
  call_user_func(array($this, get_parent_class($bt[1]['class']) . '::do_something'));
}

它不漂亮(我特别讨厌调用 debug_backtrace( ) for this),但它将对象上下文设置为$ this,并处理从对象层次结构中间某处的方法调用方法的情况。

It's not pretty (I particularly hate calling debug_backtrace() for this), but it keeps the object context set to $this, and handles the case where the method is called from a method somewhere in the middle of the object hierarchy.

对于那些发现我的例子令人困惑和/或想知道的人你为什么要这样做?我道歉,并提供以下附加示例,希望更具说明性,更接近原始问题。它要长得多,但希望能说明为什么我关心保持这个设置正确,还说明为什么我不能硬编码任何特定的类名或使用$ this-> method()。避免无限循环始终是我的首要任务。 : - )

For those who found my example confusing and/or wanted to know "Why would you want to do this?" I apologize, and provide the following additional example, which is hopefully more illustrative and closer to the original problem. It is considerably longer, but hopefully shows why I care about keeping $this set properly, and also shows why I can't hard-code any particular class name or use $this->method(). Avoiding infinite loops is always a priority with me. :-)

class class1_required_type { }
class class2_required_type { }
class class3_required_type { }
class class4_required_type { }

class class1 {
  protected $data = array();
  protected function checkType($name, $value, $requiredType) {
    print "In class1::checkType()\n";
    if (get_class($value) === $requiredType) {
      $backtrace = debug_backtrace();
      call_user_func(array($this, get_parent_class($backtrace[1]['class']) . "::mySet"), $name, $value);
    } else {
      throw new Exception(get_class($this) . "::mySet('" . $name . "') requires an object of type '" . $requiredType . "', but got '" . get_class($value) . "'");
    }
  }
  function mySet($name, $value) {
    print "In class1::mySet()\n";
    if ($name === 'class1_field') {
      $this->checkType($name, $value, 'class1_required_type');
    } else {
      $this->data[$name] = $value;
    }
  }
  function dump() {
    foreach ($this->data as $key => $value) {
      print "$key: " . get_class($value) . "\n";
    }
  }
}

class class2 extends class1 {
  function mySet($name, $value) {
    print "In class2::mySet()\n";
    if ($name === 'class2_field') {
      $this->checkType($name, $value, 'class2_required_type');
    } else {
      parent::mySet($name, $value);
    }
  }
}

class class3 extends class2 {
  function mySet($name, $value) {
    print "In class3::mySet()\n";
    if ($name === 'class3_field') {
      $this->checkType($name, $value, 'class3_required_type');
    } else {
      parent::mySet($name, $value);
    }
  }
}

class class4 extends class3 {
  function mySet($name, $value) {
    print "In class4::mySet()\n";
    if ($name === 'class4_field') {
      $this->checkType($name, $value, 'class4_required_type');
    } else {
      parent::mySet($name, $value);
    }
  }
}

$obj = new class4;
$obj->mySet('class3_field', new class3_required_type);
$obj->dump();

我试图避免重复checkType()函数,但仍提供正确的行为即使层次结构变得任意大。

I'm trying to avoid duplication of the "checkType()" function, yet still provide correct behavior even when the hierarchy gets arbitrarily large.

当然,更优雅的解决方案是最受欢迎的。

More elegant solutions are, of course, most welcome.

这篇关于如何从继承的方法中调用PHP父方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆