PHP Switch enter in string string case when integer indexed

PHP Switch enter in string Case when integer indexed

提问人:Bruno Natali 提问时间:1/30/2020 更新时间:1/30/2020 访问量:204

问:

我不知道出了什么问题。PHP 只是假设我的数组的索引 (int) 0 等价于 Switch 的第一个 Case 并抛出错误。

假设我输入一个这样的数组:

$config = [
    "testA" => true,
    "testB" => 22,
    0 => 0
];

我的代码示例:

foreach($config as $name => $value) {
    switch($name) {
        case "testA":
            if (!is_bool($value)) throw new \Exception( "Configuration '$name' must be boolean.");
            $this->systemVarA = $value;
            break;
        case "testB":
            if (!is_int($value)) throw new \Exception( "Configuration '$name' must be integer.");
            $this->systemVarB = $value;
            break;
    }
}

当然,$config[“testA”] 和 $config[“testB] 工作正常,但是当 foreach 达到 $config[0] 时,触发了”testA“,应用程序向我抛出异常。

我有一个解决方法是在 Switch 之前,像这样转换变量$name:

$name = (is_int($name) ? (string)$name : $name); // Used this because I already have other inline if

但它接缝是一个错误。我已经在Windows主机上测试了PHP 7.1,7.3和7.4。

PHP 异常 switch-statement 案例

评论

0赞 Progrock 1/30/2020
你可以做这样的事情:3v4l.org/uYHWA

答:

1赞 Vladimir Tarkhanov 1/30/2020 #1

这是因为PHP在switch部分使用==运算符。 当您尝试将 int(0) 与字符串 “testA” 进行比较时,它总是返回 true。 检查一下:

if(0 == "some string") echo "Equals!";

此代码打印“Equals!”。

评论

0赞 Honk der Hase 1/30/2020
没错......它是由松散类型系统引起的,它试图将字符串内容“转换”为 Integer。一旦遇到第一个非数字字符,此过程就会停止(例如,在本例中立即)...转换的结果是 0 (零)
1赞 Bruno Natali 1/30/2020
明白了!!寻找这个“==”比较器问题,我找到了其他解决方法:switch(TRUE){case ("testA" === $name): //blah break;}
0赞 Stephen R 2/6/2020
@BrunoNatali看到我的答案以获得更清洁的解决方案
0赞 Bruno Natali 2/6/2020
@StephenR 我看到了你的解决方案,但正如我在原始问题中提到的,我已经得到了这种投射方法的解决方法。谈到switch中的“true”技巧,我选择这个而不是使用if & else if,以保持良好的开关结构,并在其他程序员读取我的代码时提供良好的视觉效果。
1赞 Stephen R 1/30/2020 #2

弗拉基米尔的回答正确地确定了原因。这里有一个解决方法:将测试值转换为字符串,因为您正在与字符串进行比较。

switch( (string) $name ) {
    ...
}

是的,您可以使用“反转技巧”,但此时,您不妨直接使用!switch(TRUE){case ("testA" === $name): ... }elseif