将整数视为'truthy'值

时间:2013-10-01 13:56:39

标签: php switch-statement

我有一个数组作为索引使用'foreach'循环和switch语句迭代: -

$test = array(1, 2, 3, 'test' => 'value');
foreach ($test as $k => $v)
{
    switch ($k)
    {
        case 'test': 
            echo $v . "\n"; 
            break;
    }
}

输出是。

1
value

Switch似乎处理字符串'test'和整数1相同,这似乎不正确。

5 个答案:

答案 0 :(得分:3)

这是因为任何字符串在与整数进行松散比较时都会转换为整数。如果字符串不以数字字符开头,则此强制转换的结果通常为零。

$test = 'test';
var_dump((int) $test); // int(0)
case中{p> switch次比较是松散的比较,而非严格(== vs ===)。

鉴于上述情况,这是循环中发生的事情,因为您正在打开(0-indexed)而不是值:

0 == 'test'      // true
1 == 'test'      // false
2 == 'test'      // false
'test' == 'test' // true

有关详细信息,请参阅string conversion to numbers

答案 1 :(得分:1)

解决方案是将索引转换为字符串。

switch ($k . '')
{
    ...
}

答案 2 :(得分:1)

我不是百分之百确定为什么会发生这种情况,但我怀疑,因为switch使用松散的比较(==而不是===),它会将0视为'真实',因此执行你的情况。

一种解决方法是测试传递的值是否为字符串: -

$test = array(1, 2, 3, 'test' => 'value');
foreach ($test as $k => $v)
{
    switch (is_string($k))
    {
        case 'test':
            echo $v . "\n";
            break;
    }
}

See it working

但是,我不确定它是否比你的解决方案更好,但对我来说,它更有意义。

答案 3 :(得分:1)

你的答案很简单。

由于switch执行与普通PHP类型判断的比较,你的第一个数组元素将通过检查,因为它有0键,等于test因为(int)强制转换'test'0

您可以为0索引元素指定任何值,并在支票中查看。但是如果你做的话

$test = array(1=>1,2=>2, 3=>3, 'test' => 'value');

- 您只会看到'value'通过了支票

答案 4 :(得分:0)

您需要使用break来避免此行为 像这样

switch ((string)$k)
{
    case 'test':
        echo $v . "\n";
        break;
    default: echo "-\n";
}