Bug #78304 [Com]: Switch statement and first case cannot be in separate code blocks

From: Date: Wed, 17 Jul 2019 10:33:06 +0000
Subject: Bug #78304 [Com]: Switch statement and first case cannot be in separate code blocks
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-221833@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78304&edit=1

 ID:                 78304
 Comment by:         benjamin dot morel at gmail dot com
 Reported by:        benjamin dot morel at gmail dot com
 Summary:            Switch statement and first case cannot be in
                     separate code blocks
 Status:             Open
 Type:               Bug
 Package:            Scripting Engine problem
 Operating System:   Fedora
 PHP Version:        7.3.7
 Block user comment: N
 Private report:     N

 New Comment:

Thanks for the explanation! I forgot about the collapsing newline (but not spaces) after the closing
tag.

Although this makes sense, it's also very confusing in the present case (pun intended).

First of all this obviously also happens when both lines are indented:

Works:

<?php switch ($type): ?>
<?php case 'a': ?>
...

Fails:

    <?php switch ($type): ?>
    <?php case 'a': ?>
    ...

And it does allow whitespace between 'break' and 'case' blocks:

    <?php break; ?>
    <?php case 'b': ?>

Which is because, as I just discovered, (unreachable) statements are allowed between break and case
in PHP.

All in all, the switch...case seems to be the only place that exhibits this odd behaviour.
Couldn't the parser handle this edge case?


Previous Comments:
------------------------------------------------------------------------
[2019-07-17 10:11:44] nikic@php.net

As the error message indicates, your problem here is the indentation. Doing something like

<?php switch ($type): ?>
<?php case 'a': ?>

will work fine. But as you indented the case block, you are basically doing the equivalent of:

switch ($type): ;
    echo '    ';
    case 'a':

which is of course not allowed.

------------------------------------------------------------------------
[2019-07-17 10:03:58] benjamin dot morel at gmail dot com

Description:
------------
When using PHP as a template engine, it can be useful to break statements into separate code blocks.
For example, this works fine with foreach:

<?php foreach ($users as $user): ?>
    <span><?= ... ?></span>
<?php endforeach; ?>

The same thing does not work with switch:

<?php switch ($type): ?>
    <?php case 'a': ?>
        <span>...</span>
    <?php break; ?>

    <?php case 'b': ?>
        <span>...</span>
    <?php break; ?>
<?php endswitch; ?>

Which fails with a parse error:

> Parse error: syntax error, unexpected '    ', expecting endswitch (T_ENDSWITCH) or
> case (T_CASE) or default (T_DEFAULT)

For this to work, the first case must be in the same code block as the switch. This works fine:

<?php switch ($type):
    case 'a': ?>
        <span>...</span>
    <?php break; ?>

    <?php case 'b': ?>
        <span>...</span>
    <?php break; ?>
<?php endswitch; ?>

I believe this is a bug.

Test script:
---------------
<?php $type = 'a'; ?>

<?php switch ($type): ?>
    <?php case 'a': ?>
        This is A
    <?php break; ?>
    <?php case 'b': ?>
        This is B
    <?php break; ?>
<?php endswitch; ?>

Expected result:
----------------
This is A

Actual result:
--------------
Parse error: syntax error, unexpected '    ', expecting endswitch (T_ENDSWITCH) or case
(T_CASE) or default (T_DEFAULT) in ...


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=78304&edit=1


Thread (7 messages)

« previous php.bugs (#221833) next »