Calling a private method from an inherited class

I want to implement a hook system in my simple ORM, in 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(); 

This results in a fatal error:

Fatal error: call to private method. Payment :: before_save () from the Record context to

Has the meaning.

I can change the scope of the public, but it seems ugly: no one except Payment has anything to do with before_save() . It is best to leave private, IMHO.

How to make a record call a private method for a class that inherits a record?

+4
source share
5 answers

Add a dummy before_save function to the Record class, set it to be accessible for protection. Now all classes that inherit from Record will have this function, if they do not overwrite it, there is NOTHING. If they overwrite it, it can implement the desired functionality.

 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(); } } 
+5
source

Check error message

 Call to private method Payment::before_save() from context 'Record' 

This means that you are trying to call the function defined in Payment while you are within Record . The Record class does not have a before_save method, because it is more up in the inheritance chain than where the function is defined.

In other words, since the parent-child relationship is Record (is parent of) Payment , Payment has access to the Records functions (due to inheritance from the parent), but not vice versa (the parent cannot "inherit" the child class of the function). You can protect your function, which will give it access up and down the inheritance chain, but you may want to rethink the architecture and decide whether you want it. Ideally, you should have a function defined in Record and override it in Payment

Also (and maybe I'm wrong), but checking explicitly for method_exists usually not required unless you are creating a truly dynamic system where runtime classes can overlap and / or be generated. If you define a class-based system from scratch, and you know how you stitch the various parts together, you usually will not need to check at runtime if method_exists ... just a thought ..

+4
source

Visibility and inheritance rules in PHP:

Declared protected members can only be accessed within the class itself and the inherited and parent classes

+2
source

class test {

 private function pri($val){ return $val; } function caller(){ return $this->pri(5); } 

}

$ testobj = new test; echo $ testobj-> caller ();

You will get 5 as output.

This way you can access the private function of the class.

0
source

Source: https://habr.com/ru/post/1436386/


All Articles