Laravel 5中的Switch - Blade

98

我该如何在Blade模板中使用switch语句?当我尝试使用以下代码时:

@switch($login_error)
    @case(1)
        `E-mail` input is empty!
        @break
    @case(2)
        `Password` input is empty!
        @break
@endswitch

在结果中,我以纯文本形式看到这段文字。在我的一些代码片段中,我更喜欢使用switch语句,因为对我来说比使用if语句更清晰。

但如果不可能,那就写if语句。


3
这是一个关于 Laravel 框架的问题,有人在使用该框架时遇到了一个错误。在这个 GitHub 页面上,有其他用户提供了一些解决方法和建议。 - ceejayoz
@ventaquil 所选答案是错误的。能否将答案更改为我发布的答案? - captainblack
@captainblack 抱歉,但这个解决方案适用于 Laravel 5.2+ - 我们正在使用 5.1 LTS。 - ventaquil
4
Laravel 5.5 引入了 switch 语句。您的代码应该能够正确渲染。 - szaman
9个回答

162

2020年更新答案

自Laravel 5.5版本起,@switch指令已内置于Blade中。使用方法如下所示。

@switch($login_error)
    @case(1)
        <span> `E-mail` input is empty!</span>
        @break

    @case(2)
        <span>`Password` input is empty!</span>
        @break

    @default
        <span>Something went wrong, please try again</span>
@endswitch

旧答案

不幸的是,Laravel Blade没有switch语句。你可以使用Laravel的if else方法或者使用纯PHP switch。你可以在Blade模板中像在任何其他PHP应用程序中一样使用纯PHP。从Laravel 5.2开始,使用@php语句。

选项1:

@if ($login_error == 1)
    `E-mail` input is empty!
@elseif ($login_error == 2)
    `Password` input is empty!
@endif

30
你只需要将这些代码添加到AppServiceProvider类的启动方法中即可。
Blade::extend(function($value, $compiler){
        $value = preg_replace('/(\s*)@switch\((.*)\)(?=\s)/', '$1<?php switch($2):', $value);
        $value = preg_replace('/(\s*)@endswitch(?=\s)/', '$1endswitch; ?>', $value);
        $value = preg_replace('/(\s*)@case\((.*)\)(?=\s)/', '$1case $2: ?>', $value);
        $value = preg_replace('/(?<=\s)@default(?=\s)/', 'default: ?>', $value);
        $value = preg_replace('/(?<=\s)@breakswitch(?=\s)/', '<?php break;', $value);
        return $value;
    });

然后你可以这样使用:

@switch( $item )
    @case( condition_1 )
        // do something
    @breakswitch
    @case( condition_2 )
        // do something else
    @breakswitch
    @default
        // do default behaviour
    @breakswitch
@endswitch

尽情享受吧~


这个不起作用。解析错误,期望"endswitch (T_ENDSWITCH)"' 或 &quot;case (T_CASE)&quot;&#039; 或 "default (T_DEFAULT)` - andres.gtz
5
这些评论后面还有人点赞吗?这有效吗? - Jonathan
1
使用Laravel 5.4对我来说不起作用。FatalThrowableError:找不到类'App\Providers\Blade'。 - Kyle Challis
1
它在5.5上可以工作。我只是好奇如何让它与phpstorm自动完成(或任何IDE)一起工作@Germey? - Michael Villeneuve
@KyleChallis 在 Blade 前面加上 \,或者在文件顶部加上 use Blade - Marjeta
显示剩余2条评论

22

在 Laravel 5.2 及以上版本中:

将您平常的代码写在 PHP 起始和结束标记之间即可。

@php
switch (x) {
    case 1:
        //code to be executed
        break;
    default:
        //code to be executed
}
@endphp

2
这个@php语法在L5.2以上非常有用。 - Alexander Kim

7
在Laravel 5.1中,这个在Blade中可以正常工作:
<?php
    switch( $machine->disposal ) {
        case 'DISPO': echo 'Send to Property Disposition'; break;
        case 'UNIT':  echo 'Send to Unit'; break;
        case 'CASCADE': echo 'Cascade the machine'; break;
        case 'TBD':   echo 'To Be Determined (TBD)'; break;
    }
?>

7

1
您可以像这样扩展 Blade:

    Blade::directive('switch', function ($expression) {
        return "<?php switch($expression): ?>";
    });
    Blade::directive('case', function ($expression) {
        return "<?php case $expression: ?>";
    });
    Blade::directive('break', function () {
        return "<?php break; ?>";
    });
    Blade::directive('default', function () {
        return "<?php default: ?>";
    });
    Blade::directive('endswitch', function () {
        return "<?php endswitch; ?>";
    });

您可以使用以下内容:
@switch($test)
@case(1)
        Words
@break
@case(2)
    Other Words
    @break
@default
    Default words
@endswitch

然而请注意 http://php.net/manual/en/control-structures.alternative-syntax.php 中的警告。
如果在 switch(): 和第一个 case 之间有任何空格,则整个代码块将失败。这是 PHP 的限制,而不是 Blade 的限制。您可以通过强制使用正常语法来绕过它,例如:
Blade::directive('switch', function ($expression) {
    return "<?php switch($expression) { ?>";
});
Blade::directive('endswitch', function ($) {
    return "<?php } ?>";
});

但这感觉有点不对。

0

这有点偏题,但出于某种原因,如果“cases”是字符串,则使用双引号如此@case("foo")不像预期的那样工作。如果您遇到此类问题,单引号似乎可以解决问题,因此请改用@case('foo')而不是@case("foo")。也许有更多信息的人可以阐明这一点。

敬礼。


-2
为了解决'switch ()'中的空格问题,您可以使用以下代码:
Blade::extend(function($value, $compiler){
    $value = preg_replace('/(\s*)@switch[ ]*\((.*)\)(?=\s)/', '$1<?php switch($2):', $value);
    $value = preg_replace('/(\s*)@endswitch(?=\s)/', '$1endswitch; ?>', $value);
    $value = preg_replace('/(\s*)@case[ ]*\((.*)\)(?=\s)/', '$1case $2: ?>', $value);
    $value = preg_replace('/(?<=\s)@default(?=\s)/', 'default: ?>', $value);
    $value = preg_replace('/(?<=\s)@breakswitch(?=\s)/', '<?php break;', $value);
    return $value;
  });

-6

当您在视图中开始使用switch语句时,通常表明您可以进一步重构代码。业务逻辑不应该放在视图中,我建议您在控制器中执行switch语句,然后将其结果传递给视图。


10
公正地说,switch语句确实可以存在于视图中。例如,如果你要根据表格中的数据范围设置CSS类,你不会想在控制器中嵌入显示逻辑。 - CashIsClay
“业务逻辑不应该出现在视图层”,业务逻辑应该放在视觉层、逻辑层和持久层。虽然这样做很繁琐,但是高质量的代码都会这么做。 - magallanes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接