切换到 Laravel 5-Blade

如何在刀片模板中使用开关? 当我使用:

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

因此,我看到这个文本作为明文。我更喜欢在几段代码中使用 switch,因为它比使用 if 时更干净。

但如果不可能,就写下来。

151797 次浏览

Updated 2020 Answer

Since Laravel 5.5 the @switch is built into the Blade. Use it as shown below.

@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

Older Answer

Unfortunately Laravel Blade does not have switch statement. You can use Laravel if else approach or use use plain PHP switch. You can use plain PHP in blade templates like in any other PHP application. Starting from Laravel 5.2 and up use @php statement.

Option 1:

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

When you start using switch statements within your views, that usually indicate that you can further re-factor your code. Business logic is not meant for views, I would rather suggest you to do the switch statement within your controller and then pass the switch statements outcome to the view.

You can just add these code in AppServiceProvider class boot method.

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;
});

then you can use as:

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

Enjoy It~

IN LARAVEL 5.2 AND UP:

Write your usual code between the opening and closing PHP statements.

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

In Laravel 5.1, this works in a 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;
}
?>

You can extend blade like so:

    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; ?>";
});

You can then use the following:

@switch($test)
@case(1)
Words
@break
@case(2)
Other Words
@break
@default
Default words
@endswitch

However do note the warnings in : http://php.net/manual/en/control-structures.alternative-syntax.php

If there is any whitespace between the switch(): and the first case then the whole code block will fail. That is a PHP limitation rather than a blade limitation. You may be able to bypass it by forcing the normal syntax e.g.:

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

But this feels a bit wrong.

To overcome the space in 'switch ()', you can use code :

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;
});

It's a bit off-topic but for some reason, if the 'cases' are strings, using double quotes as such @case("foo") is not working as expected, in case you're experiencing such a problem, single quotes seem to work, so instead of @case("foo") use @case('foo'). Maybe someone with more information could shed some light on this.

Regards.