Pro PHP- Patterns, Frameworks, Testing and More

(vip2019) #1

(^78) CHAPTER 7 ■ REFLECTION API
Chapter 1), this method does not require an instance of the class to operate and is thus much
more efficient.
You will also notice that you store instances of ReflectionClass and not instances of the
classes or the names as strings. This is because creating a reflection class has some overhead,
and you will need to determine if a plug-in has certain properties before invoking methods on
the plug-in later. You might as well store it now, so that you don’t need to execute the instanti-
ation twice.
Now that you can locate your plug-ins, you need to create a mechanism that determines
the subset of application functionality with which the plug-in will interact. A plug-in that contains
menu items, for example, will have a method defined for adding entries to the menu, while a
sidebar plug-in might not have such a method.
To determine if a class implements a method, you can use the hasMethod() method of the
ReflectionClass. Listing 7-5 shows the menu-compiling function for this example.
Listing 7-5. Determining Class Members for a Menu
function computeMenu() {
$menu = array();
foreach(findPlugins() as $plugin) {
if($plugin->hasMethod('getMenuItems')) {
$reflectionMethod = $plugin->getMethod('getMenuItems');
if($reflectionMethod->isStatic()) {
$items = $reflectionMethod->invoke(null);
} else {
//If the method isn't static we need an instance
$pluginInstance = $plugin->newInstance();
$items = $reflectionMethod->invoke($pluginInstance);
}
$menu = array_merge($menu, $items);
}
}
return $menu;
}
The code in Listing 7-5 may look a little complex at first, but it’s really quite simple. The
purpose of the computeMenu() function is to return an array of menu it ems. Assume for the moment
that there is a menuItem class, and instances of the class will be stored in $menu as array entries.
Next, you use the findPlugins() function to locate all the plug-ins. Since you stored the
ReflectionClass instances for each plug-in in the result array, you don’t need to re-create those
instances, and you can simply iterate the plug-ins to access the reflection information for each.
Your application now needs to determine if each plug-in has menu items. By design, creating
menu items is optional for your plug-ins. You determine if the plug-in contains this capability
by using the hasMethod() method of the ReflectionClass instance. If the method is located,
then you will need to get a reflector for the method.
The getMethod() method of the ReflectionClass instance returns another reflector class:
ReflectionMethod. Like ReflectionClass, ReflectionMethod allows you to access metadata, but
this metadata is about the method, rather than the class. By getting a ReflectionMethod, you
can introspect the method and determine its metadata.
McArthur_819-9C07.fm Page 78 Friday, February 22, 2008 8:59 AM

Free download pdf