|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #78304 Switch statement and first case cannot be in separate code blocks
Submitted: 2019-07-17 10:03 UTC Modified: 2019-07-19 12:54 UTC
From: benjamin dot morel at gmail dot com Assigned:
Status: Open Package: Scripting Engine problem
PHP Version: 7.3.7 OS: Fedora
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: benjamin dot morel at gmail dot com
New email:
PHP Version: OS:


 [2019-07-17 10:03 UTC] benjamin dot morel at gmail dot com
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': ?>
    <?php break; ?>

    <?php case 'b': ?>
    <?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': ?>
    <?php break; ?>

    <?php case 'b': ?>
    <?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 ...


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-07-17 10:11 UTC]
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:33 UTC] benjamin dot morel at gmail dot com
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:


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


    <?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 seems to be the only place that exhibits this odd behaviour. Couldn't the parser handle this edge case?
 [2019-07-17 10:47 UTC]
If the indentation is located between the switch and first case then when should it be outputted? For all cases? For only the first one? Or should it not be outputted at all?

Avoid the whole problem with

<?php switch ($type): case 'a': ?>
 [2019-07-17 11:07 UTC] benjamin dot morel at gmail dot com
The idea would be:

- (...):
- T_INLINE_HTML containing only whitepace

Would drop the last 3 tokens. Isn't that feasible?
 [2019-07-19 12:54 UTC]
-Type: Bug +Type: Feature/Change Request
 [2019-07-19 12:54 UTC]
As has been explained, this is not a bug, so I'm changing to
feature request.

I think that this FR should be discussed on internals (or
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Dec 12 14:01:23 2019 UTC