允许PHP函数变量是字符串还是数组是模式还是反模式?

时间:2011-01-20 13:46:48

标签: php overloading

来自 C#我习惯用可变类型的参数重载我的方法。由于您无法在 PHP 中执行此操作,因此我经常创建方法,例如下面接受变量的示例,然后我检查类型并采取相应措施:

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/>';
    }
}

输出:

3
3
3
5
4

这给了我与C#相同的功能,但它看起来有点乱,好像有更好的方法。

这是在PHP(5.3)中进行方法重载的可接受方式还是有更好的方法?

3 个答案:

答案 0 :(得分:11)

我知道很多框架都会对某些有意义的函数执行此操作,就像PHP的一些核心函数一样。 “好”用法和“差”用法之间的区别在于文档(docblock)。文档需要指出param是混合类型和不同的可接受变量类型。

例如:

<?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;
}

答案 1 :(得分:3)

就像你说的那样,实际上并没有像C#那样在PHP中接受多个类型参数的方法,但只要你在用它们做任何事情之前检查参数是什么类型的话,这不应该引起问题。

许多原生PHP函数接受混合类型参数,例如: str_replace()

答案 2 :(得分:3)

我不喜欢打死马,但我仍然会在这里称重。

我不认为这是一种反模式;正如@Merijn所指出的,许多本机PHP函数都接受混合类型参数。此外,作为您自己的许多情况,要求简洁的函数接受给定类型的元素或集合,而不是将它分割为两个函数。

转换为(array)是实现此功能的快捷方式:

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

使用$foo = (array) $foo;$foo = array($foo);更好 1 ,因为当$foo已经是数组时,它不会再次包装它。


参考


1 使用标量生成所需的结果;对象产生不同的结果。转换为数组的对象将枚举属性,因此请谨慎使用。