PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 4 ■ ADVANCED FEATURES


}


In this example I work with “setter” methods rather than “getters.” If a user attempts to assign to an
undefined property, the __set() method is invoked with the property name and the assigned value. I test
for the existence of the appropriate method, and invoke it if it exists. In this way I can filter the assigned
value.


■Note Remember that methods and properties in PHP documentation are frequently spoken of in static terms in


order to identify them with their classes. So you might talk about the Person::$name property, even though the


property is not declared static and would in fact be accessed via an object.


So if I create a Person object and then attempt to set a property called Person::$name, the set()
method is invoked, because this class does not define a $name property. The method is passed the string
“name” and the value that the client assigned. How the value is then used depends upon the
implementation of
set(). In this example, I construct a method name out of the property argument
combined with the string “set”. The setName() method is found and duly invoked. This transforms the
incoming value and stores it in a real property.


$p = new Person();
$p->name = "bob";
// the $_name property becomes 'BOB'


As you might expect, unset() mirrors set(). When unset() is called on an undefined property,
unset() is invoked with the name of the property. You can then do what you like with the information.
This example passes null to a method resolved using the same technique as you saw used by
set().


function __unset( $property ) {
$method = "set{$property}";
if ( method_exists( $this, $method ) ) {
$this->$method( null );
}
}


The call() method is probably the most useful of all the interceptor methods. It is invoked when
an undefined method is called by client code.
call() is invoked with the method name and an array
holding all arguments passed by the client. Any value that you return from the call() method is
returned to the client as if it were returned by the method invoked.
The
call() method can be useful for delegation. Delegation is the mechanism by which one
object passes method invocations on to a second. It is similar to inheritance, in that a child class passes
on a method call to its parent implementation. With inheritance the relationship between child and
parent is fixed, so the ability to switch the receiving object at runtime means that delegation can be more
flexible than inheritance. An example clarify things a little. Here is a simple class for formatting
information from the Person class:


class PersonWriter {


function writeName( Person $p ) {
print $p->getName()."\n";
}

Free download pdf