php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80490 Switch choose a wrong block, if int(0) is a value
Submitted: 2020-12-07 12:08 UTC Modified: 2020-12-07 13:04 UTC
From: miso at fykos dot cz Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.4.13 OS: ubuntu 18.04
Private report: No CVE-ID: None
 [2020-12-07 12:08 UTC] miso at fykos dot cz
Description:
------------
When argument of switch is a int(0), switch choose a wrong statement.

Test script:
---------------
<?php

$key = 0;
switch ($key) {
    case 'a':
        echo 'break';
        break;
    default:
        echo 'default';
        break;
}

Expected result:
----------------
'default'

Actual result:
--------------
'break'

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-12-07 12:52 UTC] rjrjdjdu at dfjdrj dot com
learn about type juggeling - "a" casted to int is 0
 [2020-12-07 12:56 UTC] peehaa@php.net
-Status: Open +Status: Not a bug
 [2020-12-07 12:56 UTC] peehaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

In particular:

https://www.php.net/manual/en/control-structures.switch.php and https://www.php.net/manual/en/language.types.type-juggling.php and
 [2020-12-07 13:04 UTC] dharman@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

You are using switch statement which performs loose comparison. Up to PHP 7.4 the type system was treating 0 == 'a'. Since PHP 8 the type system and loose comparisons have been improved. The behaviour you are seeing is expected in PHP 7.4. See it online here: https://3v4l.org/lKu3p
The following example might be also helpful to see how to comparison is performed:  https://3v4l.org/rmTmq

If you are already on PHP 8, you can avail of "match" statement which performs a strict comparison, but works in a similar manner to switch

However, it looks like you would benefit more from an if statement instead. 

$key = 0;
if('a' === $key) {
    echo 'break';
} else {
    echo 'default';
}

If you want to use switch and perform strict comparison, then you can abuse the structure and do the following:

switch (true) {
    case 'a' === $key:
        echo 'break';
        break;
    default:
        echo 'default';
        break;
}

But it would be more appropriate to use an if statement in this case.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Apr 28 23:01:32 2024 UTC