7.10.1 Problem
You want to execute different code depending on
the number and type of arguments passed to a method.
7.10.2 Solution
PHP doesn't support method polymorphism as a built-in feature.
However, you can emulate it using various type-checking functions. The following
combine( ) function uses is_numeric(),
is_string(), is_array(), and is_bool():
// combine() adds numbers, concatenates strings, merges arrays,
// and ANDs bitwise and boolean arguments
function combine($a, $b) {
if (is_numeric($a) && is_numeric($b)) {
return $a + $b;
}
if (is_string($a) && is_string($b)) {
return "$a$b";
}
if (is_array($a) && is_array($b)) {
return array_merge($a, $b);
}
if (is_bool($a) && is_bool($b)) {
return $a & $b;
}
return false;
}
7.10.3 Discussion
Because PHP doesn't allow you to declare a variable's type in a
method prototype, it can't conditionally execute a different method based on the
method's signature, as can Java and C++. You can, instead, make one function and
use a switch statement to manually recreate this
feature.
For example, PHP lets you edit images
using GD. It can be handy in an image class to be able to pass in either the
location of the image (remote or local) or the handle PHP has assigned to an
existing image stream. Example
7-2 shows a pc_Image class that does just that.
Example 7-2. pc_Image class
class pc_Image {
var $handle;
function ImageCreate($image) {
if (is_string($image)) {
// simple file type guessing
// grab file suffix
$info = pathinfo($image);
$extension = strtolower($info['extension']);
switch ($extension) {
case 'jpg':
case 'jpeg':
$this->handle = ImageCreateFromJPEG($image);
break;
case 'png':
$this->handle = ImageCreateFromPNG($image);
break;
default:
die('Images must be JPEGs or PNGs.');
}
} elseif (is_resource($image)) {
$this->handle = $image;
} else {
die('Variables must be strings or resources.');
}
}
}
In this case, any string passed in is treated as the location
of a file, so we use pathinfo() to grab the file extension. Once we know the extension, we
try to guess which ImageCreateFrom( ) function
accurately opens the image and create a handle.
If it's not a string, we're dealing directly with a GD stream,
which is of type resource. Since there's no conversion necessary, we
assign the stream directly to $handle. Of course, if you're using this
class in a production environment, you'd be more robust in your error handling.
Method polymorphism also encompasses methods with differing
numbers of arguments. The code to find the number of arguments inside a method
is identical to how you process variable argument functions using
func_num_args( ). This is discussed in Section 6.6.