PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 4 ■ ADVANCED FEATURES


elegant way of creating anonymous functions? Well since PHP 5.3 there is a much better way of doing it.
You can simply declare and assign a function in one statement. Here's the previous example using the
new syntax:


$logger2 = function( $product ) {
print " logging ({$product->name})\n";
};


$processor = new ProcessSale();
$processor->registerCallback( $logger2 );


$processor->sale( new Product( "shoes", 6 ) );
print "\n";
$processor->sale( new Product( "coffee", 6 ) );


The only difference here lies in the creation of the anonymous variable. As you can see, it’s a lot
neater. I simply use the function keyword inline, and without a function name. Note that because this is
an inline statement, a semi-colon is required at the end of the code block. Of course if you want your
code to run on older versions of PHP, you may be stuck with create_function() for a while yet. The
output here is the same as that of the previous example.
Of course, callbacks needn’t be anonymous. You can use the name of a function, or even an object
reference and a method, as a callback. Here I do just that:


class Mailer {
function doMail( $product ) {
print " mailing ({$product->name})\n";
}
}


$processor = new ProcessSale();
$processor->registerCallback( array( new Mailer(), "doMail" ) );


$processor->sale( new Product( "shoes", 6 ) );
print "\n";
$processor->sale( new Product( "coffee", 6 ) );


I create a class: Mailer. Its single method, doMail(), accepts a $product object, and outputs a
message about it. When I call registerCallback() I pass it an array. The first element is a $mailer object,
and the second is a string that matches the name of the method I want invoked. Remember that
registerCallback() checks its argument for callability. is_callable() is smart enough to test arrays of
this sort. A valid callback in array form should have an object as its first element, and the name of a
method as its second element. I pass that test here, and here is my output:


shoes: processing
mailing (shoes)


coffee: processing
mailing (coffee)


Of course you can have a method return an anonymous function. Something like this:
Free download pdf