What is a loose comparison?

26

In documentation of PHP, about switch says:

  

Note : Note that switch / case does loose comparison .

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

    
asked by anonymous 26.06.2017 / 19:15

2 answers

22

Loose comparison is the PHP default. As a weak typing language, it neglects the type rigidity at the time of purchase, so 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 you have a very large benefit, as shown in the link above.

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

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

See in ideone the probably unwanted effect of performing something that should be different.

In strong typing languages none would execute. In static typing languages would not even compile.

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

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

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

View in ideone as now the result is more intuitive not running any of the blocks since the types are different.

Given this difficulty, switch of PHP is of little use except in cases where a great discipline is used in the use of variables. Or if you use switch as a if , which again has no advantage. Particularly I do not use. In general, this mechanism was created in other languages because of performance that was better than if for these cases, but in PHP there will rarely be any gain and the syntax ends up being verbose and susceptible to errors.

You have more details on choosing if and switch .

At documentation there are tables of how comparisons are made. There is much more possibility of obtaining a true one with the loose comparison, and it is not always the one desired.

    
26.06.2017 / 19:27
16

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

$x = 1
$y = "1"

$x 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 .

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

Simple example of day to day, for those who have floated:

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

}

The above example returns true because true is equal to 1 . But it should not. This is why it is 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 = more.

Rigid comparisons with switch case

By default the switch case does not make a hard comparison, but it is possible to get around. Example:

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

        break;
}

Comparison table

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 is different from 0e830400451993494058024219903391 , not?

See the difference:

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

var_dump('0e462097431906509019562988736854' === '0e830400451993494058024219903391');
    
26.06.2017 / 19:25