PHP Classes and Objects
Using Method Polymorphism
Problem
You want to execute different code depending on the number and type of arguments passed to a method.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_int($a) && is_int($b)) {
return $a + $b;
}
if (is_float($a) && is_float($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;
}
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 Java and C++ can. You can, instead, make one function and use a switch statement to manually re-create 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. This Image class that does just that:
class Image {
protected $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 use pathinfo() to grab the file extension. Once you know the extension, try to guess which ImageCreate From() function accurately opens the image and create a handle.
If it’s not a string, you’re dealing directly with a GD stream, which is a type of resource. Because there’s no conversion necessary, 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().
No comments:
Post a Comment