Lord Yggdrasill wrote:Let's say every member method in a particular class of your script has like a line or a few lines of identical code, this magic method will prove to be quite useful.
Given an object of this class, will more than one of these methods be called in any given context? I ask this because your problem reminds me of the template method pattern: "define the skeleton of an algorithm in an operation, deferring some steps to subclasses."
class SomeClass {
public function __construct($arg1, $arg2...){
// code for constructor
}
public function someMethod() {
// line 1
// line 2
// line 3
$this->someMethodHook();
}
protected function someMethodHook() {}
}
class SomeClass1 extends SomeClass {
protected function someMethodHook() {
// rest of the code, specific to this particular subclass
}
}
class SomeClass2 extends SomeClass {
protected function someMethodHook() {
// rest of the code, specific to this particular subclass
}
}
class SomeClass3 extends SomeClass {
protected function someMethodHook() {
// rest of the code, specific to this particular subclass
}
}
The advantage here is that SomeClass is open to extension but closed to modification: a new specialised operation can be added just by subclassing, rather than by modifying SomeClass.
Lord Yggdrasill wrote:Now guess it should be clear, the line 1-3 are identical in the three methods and this can be annoying. You may argue that grouping these three lines into a function or a private method will work, but imagine you have more than 10 methods. You still have to write 10+ lines of repetitive code in this particular class.
It is not that much of a big deal since you can just copy and paste the function calls. The important part is that if you need to modify those three (or more) lines, you do it in one place rather than many places.
Lord Yggdrasill wrote:Now it looks alot better, isnt it?
Yeah, but then a reader who was not aware that a magic function hook exists may misunderstand the code. The template method version mitigates this problem in that the method that is called is someMethod, so the calling of someMethodHook is explicit, which is a Good Thing.
EDIT:
Lord Yggdrasill wrote:But I am not sure if this magic method exists at all. So can anyone of you inform me if such a magic method is available in PHP? If not, is there a way to 'simulate' a method like this?
You can use call for this, assuming that the template method pattern is not appropriate. Basically, you call the appropriate method in call. The method itself should be private, and possibly with a decorated name to avoid confusion.
Originally, I was against this because of my concern for readability as mentioned above, but since the methods will be private (and possibly with a decorated name), it should be clear that the call is indirect hence the reader will find __call and see that those three lines are present. Nonetheless, I suggest considering if this is appropriate or if the template method pattern is appropriate, or if just calling a private method from each method is appropriate.