我想在我的简单ORM中用PHP实现一个钩子系统:
class Record {
public function save() {
if (method_exists($this,"before_save")) {
$this->before_save();
}
//...Storing record etc.
}
}
class Payment extends Record {
private function before_save() {
$this->payed_at = time();
}
}
$payment = new Payment();
$payment->save();
这会导致致命错误:
致命错误:调用私有方法Payment :: before_save()来自
中的上下文“记录”
有道理。
我可以将范围更改为公开,但这看起来很难看:没有人但是付款与before_save()
有关。最好保密,恕我直言。
如何在继承自Record?
的类上使Record调用为私有方法答案 0 :(得分:5)
向before_save
类添加一个虚拟Record
函数,将其设置为受保护。现在,所有继承自Record
的类都将具有此功能,如果它们不覆盖它,它将执行NOTHING。如果它们覆盖它,它可以实现所需的功能。
class Record {
public function save() {
$this->before_save();
//...Storing record etc.
}
protected function before_save() {
return;
}
}
class Payment extends Record {
protected function before_save() {
$this->payed_at = time();
}
}
答案 1 :(得分:4)
检查错误消息
Call to private method Payment::before_save() from context 'Record'
这意味着当您在Payment
范围内时,您正试图调用Record
中定义的函数。类Record
没有before_save
方法,因为继承链中的向上比定义函数的位置更强
换句话说,因为父子关系是Record (is parent of) Payment
,Payment
可以访问Records
函数(由于从父级继承)但反之亦然(父级)不能“继承”子类功能)。你可以使你的函数受到保护,这将使它可以访问继承链的上下,但你可能想重新考虑体系结构并决定是否需要它。理想情况下你应该在Record
中定义函数并且有它在Payment
此外(我可能错了),但通常不需要明确检查method_exists
,除非您正在创建一个可以重叠和/或生成运行时类的真正动态系统。如果你是从头开始定义一个基于类的系统,你知道如何拼接各个部分,通常你不需要在运行时检查method_exists
......只是一个想法.. < / p>
答案 2 :(得分:2)
答案 3 :(得分:2)
PHP中的可见性和继承规则:
声明受保护的成员只能在类本身以及继承和父类
中访问
答案 4 :(得分:1)
获胜者没有回答问题。有关“公开”,“受保护”,“私有”和“最终”的信息应可在任何博客或书籍上获得。
这个问题询问如何使用继承类中的“私有”功能。这里的用例是,您被迫使用设计不当,不加选择地使用私有函数的第三方代码,并且不得不寻找使用私有函数的方法,或者派生整个仓库。
这是问题的答案。
class foo {
protected $text = "foo";
private function bar($text)
{
return $text.'->'.$this->text;
}
}
class fooChild extends foo{
protected $text = "bar";
public function barChild()
{
$r = new \ReflectionMethod(parent::class, 'bar');
$r->setAccessible(true);
//return $r->invokeArgs(new foo(), ['output']); // output->foo
return $r->invokeArgs($this, ['output']);//output->bar
}
}
echo (new fooChild())->barChild();
使用ReflectionMethod类,可以从继承类调用私有方法。您可以看到使用$ this和父对象的新实例的区别。不会从新实例的子级设置属性。
答案 5 :(得分:0)
班级考试{
private function pri($val){
return $val;
}
function caller(){
return $this->pri(5);
}
}
$ testobj = new test; echo $ testobj-&gt; caller();
您将获得5作为输出。
通过这种方式,您可以访问类的私有函数。