我希望我能清楚地写下来
案例:
我有 base 类Foo
。
Foo 可以拥有方法(例如) ::run
。
另一个班级Bar
扩展Foo
并拥有自己的方法::run
。 Bar
(以及编写Bar
)的开发人员不知道父Foo
或是否会方法::run
。
这就是Bar
想要在parent
上调用当前方法的原因。
辅助方法::callParentMethodIfExists
应该完成其工作并检查$method
上是否存在parent
。
到目前为止一切顺利:
Bar::run
Bar::run
来电::callParentMethodIfExists
::callParentMethodIfExists
调用parent::run
(如果存在)。问题:
如果现在某个班级Baz
延伸Bar
而Baz
不则使用::run
方法:
Baz::run
Bar
Bar::run
Bar::run
来电::callParentMethodIfExists
::callParentMethodIfExists
调用::parentMethodExists
并检查(这就是问题) $this
(Baz
)是否有父方法{{1} } 所以事实证明这是真的,因为::run
有一个Baz
(即parent::run
ofc)但是这不是我应该从中检查它的范围
简而言之
帮助方法Bar::run
和::callParentMethodIfExists
应该不检查::parentMethodExists
。他们应该检查范围首次出现问题的方法。
代码
工作案例
$this
不工作案例
class Foo
{
public function run()
{
echo __METHOD__ . PHP_EOL;
}
}
class Bar extends \Foo
{
public function run()
{
$this->callParentMethodIfExists(__FUNCTION__);
echo __METHOD__ . PHP_EOL;
}
/**
* Calls the given parent method if exists.
*
* @param string $method
*
* @return null|mixed
*/
protected function callParentMethodIfExists($method)
{
if ($this->parentMethodExists($this, $method)) {
return parent::$method();
}
return null;
}
/**
* @param mixed $class An object (class instance) or a string (class name).
* @param string $method The method name.
*
* @return bool
*/
public function parentMethodExists($class, $method)
{
foreach (class_parents($class) as $parent) {
if (method_exists($parent, $method)) {
return true;
}
}
return false;
}
}
class Baz extends \Bar{}
(new \Baz())->run();
// out:
// Foo::run
// Bar::run
正如您在 not not case 上看到的那样,class Foo{}
class Bar extends \Foo
{
public function run()
{
$this->callParentMethodIfExists(__FUNCTION__);
echo __METHOD__ . PHP_EOL;
}
/**
* Calls the given parent method if exists.
*
* @param string $method
*
* @return null|mixed
*/
protected function callParentMethodIfExists($method)
{
if ($this->parentMethodExists($this, $method)) {
return parent::$method();
}
return null;
}
/**
* @param mixed $class An object (class instance) or a string (class name).
* @param string $method The method name.
*
* @return bool
*/
public function parentMethodExists($class, $method)
{
foreach (class_parents($class) as $parent) {
if (method_exists($parent, $method)) {
return true;
}
}
return false;
}
}
class Baz extends \Bar{}
(new \Baz())->run();
// out:
// Fatal error: Uncaught Error: Call to undefined method Foo::run() in
类没有Foo
方法。
被叫类(::run
)是$this
。
Baz
的 Baz
继承方法::run
。
Bar
来电Bar::run
。
两个辅助方法错误地检查::callParentMethodIfExists
($this
)并找出 Baz
有一个Baz
。
实际上,两个辅助方法应该检查当前范围(parent::run
)并找出 Bar
不是否有Bar
。
我希望这是可以理解的,有人知道解决方案。
提前致谢!
/ cottton
编辑 parent::run
和::callParentMethodIfExists
也可以在::parentMethodExists
上定义或包含在Foo
中。
答案 0 :(得分:0)
也许我不了解情况,但我会写Bar::run()
就像那样简单:
public function run()
{
if (method_exists('Foo', 'run')) {
Foo::run();
}
echo __METHOD__ . PHP_EOL;
}
你知道Bar extends Foo
,没有必要对父类和所有东西进行如此多的调查。
Bar
的孩子可能会重新定义方法run()
,或者他们可能不会。只要他们在新定义中调用parent::run();
,调用链最终将会Bar::run()
调用Foo::run()
(如果存在)。