What is a loose comparison?

In the PHP documentation , about switch it says:

Note : Note that switch / case does loose comparison.

What is a loose comparison? And what is the difference between a loose comparison and a rigid one?

Author: Maniero, 2017-06-26

2 answers

Loose comparison is PHP's default. As a weak typing language, it sets aside the rigidity of types at the time of purchase, so you try to get a result, even if you are comparing bananas with apples , which is often harmful.

In general this is considered bad practice and should only be used if it has a very large benefit, as shown in the link above.

The rigid comparison, or strict as it is also called, is made with ===, taking into account the type of the data, so if the type is different, it is already guaranteed that the result is false. The loose comparison uses ==. The documentation makes it clear that at the time of switch it is this comparison that will be used. So this will go into a case

$x = "1";
switch ($x) {
    case 1:
        echo "é 1";
        break;
    case 2:
        echo "é 2";
        break;
}

See ideone The probably unwanted effect of running something that should be different. E no repl.it. also I put on GitHub to future reference .

In strong typing languages none would execute. In static typing languages I wouldn't even compile.

Note that case is a numeric type, but the value is a type string. When he tries to compare different types he gets lost.

To prevent this type of problem from occurring, unlike if or another construct where you explicitly use ===, you need to sanitize the data before comparing, unless you have confidence that he will always be right. But when you do this in practice you're not using a switch, you just use its syntax. The concept of switch is to make a deviation based on a data table, it is not to use conditions. Conceptually if it is going to use conditions, the if is more suitable, mainly used the rigid comparison:

$x = "1";
if ($x === 1) {
    echo "é 1";
} else if ($x === 2) {
    echo "é 2";
}

See ideone as now the result is more intuitive not running any of the blocks since the types are different. And no repl.it. also I put on GitHub for future reference .

Given this difficulty the switch of PHP is little useful except for cases that use a great discipline in the use of variables. Or if you use switch as if it were a if, which again has no advantage. Particularly I do not usually use. In general this mechanism was created in other languages for performance reasons which was better than if for these cases, but in PHP rarely there will be some gain and the syntax turns out to be verbose and error-prone.

Has more details about the choice of if and switch. And about the new match.

In the documentation there are tables of how comparisons are made. There is much more possibility to get a real one with the loose comparison, and it is not always the desired one.

 25
Author: Maniero, 2020-12-07 13:29:05

The loose comparison does not compare the type as in the rigid comparison.

$x = 1
$y = "1"

$x it is different from $y because although they have the same value, the first is a variable to type int and the second is of type string.

The loose comparison ignores the type and compares only the value. When it identifies that it is a number in the string, it is treated as a number. So 1 is equal to "1".

Simple everyday example, for those who stayed buoyant:

$x = 1;
if ($x == true) {

}

The above example returns true because true equals 1. But it shouldn't. So it's called loose comparison.

When you need more consistency in comparisons, use strict comparison :

$x = 1;
if ($x === true) {

} else {
    // vai entrar aqui, pois é falso.
}

Note that there is one more =.

Hard comparisons with switch case

By default the switch case does not compare rigid but it is possible to bypass. Example:

$x = 1;
switch (true) {
    case ($x === "1"):

        break;
}

Comparison table

insert the description of the image here

PHP documentation

Case study

An example of how important it is to know when to use, see this somewhat "dangerous" comparison with md5():

var_dump(md5('240610708') == md5('QNKCDZO'));

0e462097431906509019562988736854 it's different from 0e830400451993494058024219903391, right?

See the difference:

var_dump('0e462097431906509019562988736854' == '0e830400451993494058024219903391');

var_dump('0e462097431906509019562988736854' === '0e830400451993494058024219903391');
 18
Author: Daniel Omine, 2017-10-13 18:56:26