PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1
CHAPTER 3 ■ OBJECT BASICS

function outputAddresses( $resolve ) {
if (! is_bool( $resolve ) ) {
die( "outputAddress() requires a Boolean argument\n" );
}
//...
}


This approach forces client code to provide the correct data type in the $resolve argument.
Converting a string argument on the client’s behalf would be friendly but would probably present other
problems. In providing a conversion mechanism, you second-guess the context and intent of the client.
By enforcing the Boolean data type, on the other hand, you leave the client to decide whether to map
strings to Boolean values and which word will map to which value. The outputAddresses() method,
meanwhile, concentrates on the task it is designed to perform. This emphasis on performing a specific
task in deliberate ignorance of the wider context is an important principle in object-oriented
programming, and I will return to it frequently throughout the book.
In fact, your strategies for dealing with argument types will depend on the seriousness of any
potential bugs. PHP casts most primitive values for you depending on context. Numbers in strings are
converted to their integer or floating point equivalents when used in a mathematical expression, for
example. So your code might be naturally forgiving of type errors. If you expect one of your method
arguments to be an array, however, you may need to be more careful. Passing a nonarray value to one of
PHP’s array functions will not produce a useful result and could cause a cascade of errors in your
method.
It is likely, therefore, that you will strike a balance among testing for type, converting from one type
to another, and relying on good, clear documentation (you should provide the documentation whatever
else you decide to do).
However you address problems of this kind, you can be sure of one thing—type matters. The fact
that PHP is loosely typed makes it all the more important. You cannot rely on a compiler to prevent type-
related bugs; you must consider the potential impact of unexpected types when they find their way into
your arguments. You cannot afford to trust client coders to read your thoughts, and you should always
consider how your methods will deal with incoming garbage.


Taking the Hint: Object Types


Just as an argument variable can contain any primitive type, by default it can contain an object of any
type. This flexibility has its uses but can present problems in the context of a method definition.
Imagine a method designed to work with a ShopProduct object:


class ShopProductWriter {
public function write( $shopProduct ) {
$str = "{$shopProduct->title}: ".
$shopProduct->getProducer().
" ({$shopProduct->price})\n";
print $str;
}
}


You can test this class like this:

$product1 = new ShopProduct( "My Antonia", "Willa", "Cather", 5.99 );
$writer = new ShopProductWriter();
$writer->write( $product1 );


This outputs
Free download pdf