Coming from C# I'm used to overloading my methods with variably typed parameters. Si开发者_运维知识库nce you can't do this in PHP, I often create methods such as the example below which accept a variable, then I check the type and act accordingly:
showLength('one');
showLength(array(
'one',
'two',
'three'
));
function showLength($stringOrArray) {
$arr = array();
if(is_array($stringOrArray)) {
$arr = $stringOrArray;
} else if(is_string($stringOrArray)) {
$arr[] = $stringOrArray;
} else {
//exception
}
foreach ($arr as $str) {
echo strlen($str).'<br/>';
}
}
output:
3
3
3
5
4
This gives me the same functionality as in C# but it seems a bit messy, as if there is a better way.
Is this the accepted way to do method overloading in PHP (5.3) or is there a better way?
I know a lot of frameworks do this for certain functions where it makes sense, as do some of PHP's core functions. The difference between 'good' uses and 'poor' uses to me is the documentation (docblock). The documentation needs to indicate that the param is of type mixed and the different acceptable variable types.
For example:
<?php
/**
* Function used to assign roles to a user
* @param int $user_id The user's id
* @param mixed $role Either a string name of the role
* or an array with string values
*
* @return bool on success/failure
*/
function addRole($user_id, $role) {
if (!is_array($role)) {
$role = array($role);
}
foreach($role as item) {
Model::addRole($item);
}
return true;
}
I don't like to beat a dead horse, but still, I'll weigh in here.
I wouldn't consider it an anti-pattern; as @Merijn points out, many native PHP functions accept mixed type parameters. Furthermore, many circumstances as your own, require that for succinctness the function accept an element, or a collection, of a given type instead of splitting it over two functions.
Casting to (array)
is a quick and easy way to achieve this functionality:
function printStuff($stuff)
{
foreach((array) $stuff as $key => $value) {
echo sprintf('%d : %s', $key, $value) . PHP_EOL;
}
}
printStuff("foo");
// 0 : foo
printStuff(array("foo", "bar", "qux"));
// 0 : foo
// 1 : bar
// 2 : qux
Using $foo = (array) $foo;
is better1 than $foo = array($foo);
as when $foo
is already an array, it won't wrap it again.
Reference
- http://php.net/manual/en/language.types.type-juggling.php
- http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
1 Produces the desired results with scalars; objects produce different results. Objects cast to array will enumerate the properties, so use discretion.
Like you said, there isn't really a method of accepting multiple type parametersin PHP like C# does, but this shouldn't cause problems as long as you check what type the parameters are before doing anything with them.
A lot of native PHP functions accept mixed type parameters, e.g. str_replace().
精彩评论