切换语句没有中断

时间:2010-11-11 14:41:57

标签: php switch-statement

为什么switch语句中不包含break的case选项会在没有check的情况下自动转发到下一个case?

try {
    switch($param) {
        case "created":
            if(!($value instanceof \DateTime))
                throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
        case "Creator":
            if(!($value instanceof \Base\User)) {
                throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");                  
            }
        default:
            $this->$param = $value;
            break;
    }
} catch(Exception $e) {
    echo $e->getMessage();
}

如果param是“创建的”,它将在创建的案例中进行检查,这很好。当检查成功时,我希望代码继续使用默认选项,这就是没有中断的原因;但相反,它继续“创造者”而$ param!=“创造者”!

我知道如何解决这个问题(只需在我的情况下“创建”添加默认代码),但我不喜欢经常重复该代码。我的实际问题是:为什么在案例不是“创作者”的情况下继续使用“创作者”案例。

6 个答案:

答案 0 :(得分:19)

Fallthrough是一个有意的设计功能,允许使用以下代码:

switch ($command) {
  case "exit":
  case "quit":
    quit();
    break;
  case "reset":
    stop();
  case "start":
    start();
    break;
}

它的设计使得执行在不同情况下运行。

default就像其他任何情况一样,除非在没有其他情况被触发的情况下跳跃。它绝不是“在运行实际选择的案例之后执行此操作”指令。在您的示例中,您可以考虑:

  switch($param) {
    case "created":
        if(!($value instanceof \DateTime))
            throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
        break;
    case "Creator":
        if(!($value instanceof \Base\User)) {
            throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");                  
        }
        break;
}

$this->$param = $value;

这里的经验法则是,如果它不依赖于开关,则将其移出开关。

答案 1 :(得分:1)

因为它是如何完成的in C

答案 2 :(得分:1)

也许这会启发你:

Jump Table Switch Case question

答案 3 :(得分:1)

我真的不知道你想要什么。

  1. 如果你想在所有情况下运行默认的东西,只需把它放在开关之后。
  2. 如果您只想在“已创建”的情况下以默认情况运行默认内容,请交换“created”和“Creator”部分的位置,并在第一个之后放置一个中断。
  3. 如果您希望该代码仅在Creator或创建匹配时运行,则删除switch语句并使用if / else OR使用标志和以下if语句。
  4. 所有工具都在那里。

答案 4 :(得分:0)

回答你的“实际问题”:为什么在案件不是“创作者”的情况下继续使用“创作者”案例。

因为您没有break。没有它,它将继续下面的情况。我能想到的唯一解决方案是将默认代码放到案例中,然后添加break

此外,您在默认情况下不需要break,因为它是交换机块中的最后一种情况。

答案 5 :(得分:0)

在 PHP 8 中,我们有 match,类似于 switch 表达式,但明显更短:

  • 它不需要break语句
  • 它可以使用逗号将不同的手臂合二为一
  • 它返回一个值,所以你只需要赋值一次

示例:

$message = match ($statusCode) {
    200, 300 => null,
    400 => 'not found',
    500 => 'server error',
    default => 'unknown status code',
};

这是它的 switch 等价物:

switch ($statusCode) {
    case 200:
    case 300:
        $message = null;
        break;
    case 400:
        $message = 'not found';
        break;
    case 500:
        $message = 'server error';
        break;
    default:
        $message = 'unknown status code';
        break;
}

参考:https://stitcher.io/blog/php-8-match-or-switch