0

我有一个以字符串和数字作为索引的数组,我使用“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 处理为相同,这似乎不对。

4

5 回答 5

3

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

$test = 'test';
var_dump((int) $test); // int(0)

caseaswitch中的比较是松散比较,而不是严格比较(==vs ===)。

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

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

有关详细信息,请参阅字符串转换为数字

于 2013-10-02T12:24:20.897 回答
1

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

switch ($k . '')
{
    ...
}
于 2013-10-01T13:56:38.573 回答
1

你的答案很简单。

由于switch执行与普通 PHP 类型判断的比较,因此您的第一个数组元素将通过检查,因为它有0键,这等于test因为 (int) cast of 'test'is 0

您可以为索引为 0 的元素分配任何值并在您的检查中查看它。但如果你这样做

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

- 你会看到只'value'通过了你的检查

于 2013-10-02T12:26:21.167 回答
1

我不是 100% 确定为什么会发生这种情况,但我怀疑,由于switch使用松散的比较(== 而不是 ===),它会将 0 视为“真实”,因此执行您的案例。

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

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

看到它工作

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

于 2013-10-02T12:12:14.440 回答
0

你需要使用break来避免这种行为

switch ((string)$k)
{
    case 'test':
        echo $v . "\n";
        break;
    default: echo "-\n";
}
于 2013-10-01T14:00:39.737 回答