You want to execute different code depending on the number and type of arguments passed to a method.
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; }
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.
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 Recipe 6.6.
Recipe 6.6 for variable argument functions; documentation on is_string( ) at http://www.php.net/is-string, is_resource( ) at http://www.php.net/is-resource, and pathinfo( ) at http://www.php.net/pathinfo.
Copyright © 2003 O'Reilly & Associates. All rights reserved.