Sub-classes of Object allow you to attach
methods to a class dynamically at run-time. Once a method has been
attached all instances of that class in existance, or instantiated
thereafter, will have the method available. Attached methods also show up
with reflection when using the
RecessReflectionClass. Example usages of attached
methods are: the implementation of relationship methods on models, and
wrappable methods. To attach a method to a class you must first define the
target method on another class. The following detailed example
demonstrates attaching a method to a class.
Example 6.3. Attaching Methods to a sub-class of
Object
<?php include('core-bootstrap.php'); Library::import('recess.lang.Object'); class MyRecessObject extends Object {}class AttachedBehavior {
public $word = 'static'; function targetMethod(Object $object
, $lastWord) { echo "Hello, $this->word PHP $lastWord!"; } } $targetInstance = new AttachedBehavior(); $targetInstance->word = 'dynamic';
MyRecessObject::attachMethod('MyRecessObject', 'attachedMethod', $targetInstance, 'targetMethod');
$myInstance = new MyRecessObject(); $myInstance->attachedMethod('world');
// Output: Hello, dynamic PHP world!
The class we will attach a method to is
| |
The class | |
Notice that attached methods always take an instance of the class they are attached to as their first parameter. Subsequent parameters are the parameters to be passed by the attached method's call (6). | |
We've created an instance of the
| |
The call to the static method
| |
We can now call |
Underneath the covers there is some simple indirection taking place
in Object's __call method
that maps the attached method call to the target method based on entries
in the ClassDescriptor. If methods are attached
during the process which sub-classes of Object
expand annotations and build-up ClassDescriptors
then the target instance, its state, and the mapping will be automatically
cached in production mode. For more information on
ClassDescriptor, see the section called “Hooks in
Object while expanding Annotations and shaping
ClassDescriptor”
[1] This parameter a result of PHP < 5.3's lack of late
static binding. Even though the static method is invoked on the
class we are attempting to attach the method to,
MyRecessObject, until PHP 5.3 there is no
means for determining the sub-class it was called on. After
PHP5.3 this limitation has been fixed.