这是我遇到问题的代码 - 简单的foreach迭代数组。有时来自数组的元素可以具有键“mailto” - 在这种情况下它应该执行一些任务。但由于某种原因,带有“0”键的第一个元素也会进入“mailto”案例。
<?php
foreach (
array(
" this shouldnt appear, it's without mailto as key - 1",
" this shouldnt appear, it's without mailto as key - 2",
"mailto" => " this should appear ",
" this shouldnt appear, it's without mailto as key - 3",
) as $type => $text
) {
echo "#$type#\n";
switch ($type) {
case "mailto":
echo ">$type< $text\n";
break;
default:
break;
}
}
输出:
#0#
>0< this shouldnt appear, it's without mailto as key - 1
#1#
#mailto#
>mailto< this should appear
#2#
为什么会出现第一个元素?
答案 0 :(得分:5)
正如其他答案所指出的那样:switch
按值进行比较,它不会进行类型&amp;价值比较。字符串常量== 0计算结果为true的事实只是PHP奇怪/怪癖中的一个,我猜。这就是说:您可以使用“真实”,硬编码密钥,也可以使用演员:
foreach($theArray as $type => $text)
{
echo "#$type#\n";
switch ((string) $type)
{//cast key to string
case "mailto":
echo ">$type< $text\n";
break;
default:
break;
}
}
完成工作。
也就是说,你真的不需要连接你回声的字符串。事实上,it's better not to。我只是将值作为逗号分隔的常量+变量回显:
echo '#', $type, '#', PHP_EOL;// use X-platform constant
switch ((string) $type)
{
case 'mailto':
echo '>', $type, '< ', $text, PHP_EOL;
break;
}
将略微更快
答案 1 :(得分:2)
您的switch语句正在进行==
比较,这意味着php将字符串mailto
类型转换为等于0的整数。因此case语句的计算结果为true。
由于您只使用一个值,请将其更改为if语句并使用严格比较===
答案 2 :(得分:1)
使用switch/case
相等运算符实现==
构造。
现在,如果你试试这个:
>> "mailto" == 0
true
>> "mailto" == 1
false
>>
你可以看到PHP是如何做错的 对于相等性测试,“mailto”被转换为整数值0。
答案 3 :(得分:0)
通过在switch语句中添加另一个案例,似乎可以很容易地修复它,如下所示:
switch ($type)
{
case 0:
break;
case 'mailto':
echo ">$type< $text\n";
break;
default:
break;
}
我怀疑将0与'mailto'进行比较的问题正确与PHP的松散类型比较有关。当您将整数与PHP中的字符串进行比较时只有两个等号(==)时,它将返回true。
强制比较作为字符串完成的另一个修复,因此避免添加这个额外的情况是将$ type转换为字符串,如下所示:
switch ((string) $type)
{
case 'mailto':
echo ">$type< $text\n";
break;
default:
break;
}
答案 4 :(得分:0)
问题是==
中switch()
的非类型比较导致0=="mailto"
为真。
如果您需要添加其他case语句并希望保留原始结构,则可以强制第一个键为1,并避免出现问题。
foreach (
array(
1=>" this shouldnt appear, it's without mailto as key - 1",
" this shouldnt appear, it's without mailto as key - 2",
"mailto" => " this should appear ",
" this shouldnt appear, it's without mailto as key - 3",
) as $type => $text
) {
否则,只需使用严格比较===
foreach (
array(
" this shouldnt appear, it's without mailto as key - 1",
" this shouldnt appear, it's without mailto as key - 2",
"mailto" => " this should appear ",
" this shouldnt appear, it's without mailto as key - 3",
) as $type => $text
) {
echo "#$type#\n";
if($type === 'mailto'){
echo ">$type< $text\n";
}
}