PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 5 ■ OBJECT TOOLS


is_subclass_of() will tell you only about class inheritance relationships. It will not tell you that a
class implements an interface. For that, you should use the instanceof operator. Or, you can use a
function which is part of the SPL (Standard PHP Library).; class_implements() accepts a class name or
an object reference, and returns an array of interface names.


if ( in_array( 'someInterface', class_implements( $product )) ) {
print "CdProduct is an interface of someInterface\n";
}


Method Invocation


You have already encountered an example in which I used a string to invoke a method dynamically:


$product = getProduct(); // acquire an object
$method = "getTitle"; // define a method name
print $product->$method(); // invoke the method


PHP also provides the call_user_func() method to achieve the same end. call_user_func() can
invoke either methods or functions. To invoke a function, it requires a single string as its first argument:


$returnVal = call_user_func("myFunction");


To invoke a method, it requires an array. The first element of this should be an object, and the
second should be the name of the method to invoke:


$returnVal = call_user_func( array( $myObj, "methodName") );


You can pass any arguments that the target method or function requires in additional arguments to
call_user_func(), like this:


$product = getProduct(); // acquire an object
call_user_func( array( $product, 'setDiscount' ), 20 );


This dynamic call is, of course, equivalent to

$product->setDiscount( 20 );


Because you can equally use a string directly in place of the method name, like this:

$method = "setDiscount";
$product->$method(20);


the call_user_func() method won't change your life greatly. Much more impressive, though, is the
related call_user_func_array() function. This operates in the same way as call_user_func() as far as
selecting the target method or function is concerned. Crucially, though, it accepts any arguments
required by the target method as an array.
So why is this useful? Occasionally you are given arguments in array form. Unless you know in
advance the number of arguments you are dealing with, it can be difficult to pass them on. In Chapter 4,
I looked at the interceptor methods that can be used to create delegator classes. Here’s a simple example
of a __call() method:


function __call( $method, $args ) {
if ( method_exists( $this->thirdpartyShop, $method ) ) {
return $this->thirdpartyShop->$method( );
}
}

Free download pdf