我有一个数组作为索引使用'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相同,这似乎不正确。
答案 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;
}
}
但是,我不确定它是否比你的解决方案更好,但对我来说,它更有意义。
答案 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";
}