你认为这是代码味道吗?
foreach((array)$foo as $bar)
{
$bar->doStuff();
}
我应该使用它吗?
if (isset($foo) && is_array($foo))
{
foreach($foo as $bar)
{
$bar->doStuff();
}
}
任何其他好的做法都不包括设置变量和断言数组?
答案 0 :(得分:4)
他们都是代码味道。第二个是回避所有的错误信息,有点像在你的厨房着火之前关掉火警。这两个都告诉你,你不知道变量$foo
中的内容是什么,或者它是否在上面的代码中定义了。您需要重新查看代码,并确切了解$foo
发生了什么。
如果是我的代码,$ foo可能总是被定义为数组,否则为false以指示不需要数组:
if(do_we_need_an_array())
$foo = function_returning_an_array();
else
$foo = false;
[...snip...]
if($foo)
foreach($foo as $f) { ... }
答案 1 :(得分:2)
如果您正在测试是否设置了变量,则可以初始化它们:
if (! $foo or !is_array($foo))
$foo = array();
foreach($foo as $bar)
{
$bar->doStuff();
}
答案 2 :(得分:1)
就个人而言,我永远不会做第一种方法,总是选择第二种方法。
答案 3 :(得分:1)
如果$ foo应该始终是一个数组,那么如果对错误情况进行某种处理,第二种形式会好得多,例如:
if (isset($foo) && is_array($foo))
{
foreach($foo as $bar)
{
$bar->doStuff();
}
}
else
{
// This should not happen, exit angrily.
exit("Oh crap, foo isn't an array!");
}
当然,您不必退出应用程序,而是在这种情况下执行任何适当的操作,可能是日志记录或其他逻辑。
答案 4 :(得分:1)
(array)$foo != if (isset($foo) && is_array($foo))
(array)
强制转换对于将对象转换为数组或将标量转换为数组非常有用,因此您可以为可能包含单个值或数组的变量创建一致的接口。
(array)$foo == array($foo)
作为数组类型的defined in the PHP Manual。
因此,如果您需要始终使用数组,那么您提供的第一个代码段就是答案。但是,类型转换规则仍然适用,因此您可能无法获得所需内容,因此请查阅手册以获取更多信息。否则,第二个选项将阻止访问非数组的未设置变量。
就代码味道而言,我会说可以避免检查未设置的变量,但是总是知道变量将会有一个数组,而且往往会逐渐增加。所以我的目标是将is_array($foo)
if-then语句中的代码保存到最小。
答案 5 :(得分:1)
我通常这样做是为了确保foreach可以处理标量和集合:
<?php
foreach (makeSureTraversable($scalarOrCollection) as $val)
{
// Do something.
}
function
makeSureTraversable($anything)
{
if (is_array($anything) || ($anything instanceof Traversable))
{
return $anything;
}
else
{
return array($anything);
}
}
这样我也可以处理实现Traversable的类(来自SPL),这意味着允许它们在foreaches中使用。
答案 6 :(得分:0)
if (!isset($foo) && !is_array($foo)) {
throw new InvalidArgumentException('Wrong array passed');
// Or do something to recover lost array
}
foreach($foo as $bar) {
$bar->doStuff();
}
答案 7 :(得分:0)
有很多次你想编写一个函数来为参数取一个或多个值:
function getNamesById($id) { }
在这种情况下,如果使用id数组调用此函数,它应该返回一个名称数组。类似地,为了保存调用代码不必将输入包装在数组中然后解包输出,如果你只是传递一个标量,那么应该返回一个标量。考虑设计用于处理标量和数组参数的函数的可能内容:
function getNamesById($id) {
$returnAnArray = is_array($id);
$output = array();
foreach ((array)$id as $theId) {
// perform some logic
$output[] = someFunction($theId);
}
return $returnAnArray ? $output : $output[0];
}
你可以看到,在这种情况下,转换为数组肯定会让每个人都更轻松。正如他们所说的那样,你接受的是自由主义......只要记录到期望变量可能是其中之一,那么我认为没有问题。 PHP是一种duck-typed语言,既有优点也有缺点,但这是其中一个好处,所以尽情享受吧!