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 context 'Record' in
Makes sense.
I could change the scope to public, but that seems ugly: no-one but Payment has anything to do with before_save()
. It is best left private, IMHO.
How can I make Record call a private method on the class inheriting from the Record?
class test{
}
$testobj = new test; echo $testobj->caller();
You will get 5 as output.
By this way You can access the private function of a class.
Add a dummy
before_save
function to yourRecord
class, set its accessibly to protected. Now all classes that inherit fromRecord
will have this function, if they don't overwrite it it will do NOTHING. If they overwrite it, it can implement the desired functionality.change the scope to protected:
http://php.net/manual/en/language.oop5.visibility.php
Check the error message
This means that you are trying to call a function defined in
Payment
while you are withinRecord
. ClassRecord
does not have abefore_save
method because it is further up in the inheritance chain than where the function is defined.In other words since, the parent-child relation is
Record (is parent of) Payment
,Payment
has access toRecords
functions (by virtue of inheriting from the parent) but not vice-versa (parent cannot "inherit" child class functions). You can make your function protected which will give it access up and down the inheritance chain, but you might want to rethink the architecture and decide if you want it so.. Ideally you should have the function defined inRecord
and have it overridden inPayment
Also (and I might be wrong with this), but checking explicitly for
method_exists
is usually not required unless you are creating a really dynamic system where run time classes can be overlapped and/or generated. If you are defining a class based system from ground-up and you know how you are stitching up the various pieces, usually you would not need to check during run-time ifmethod_exists
...just a thought..Visibility and the rules of inheritance in PHP: