Π’Π°Π±Π»ΠΈΡ†Ρ‹ сравнСния Ρ‚ΠΈΠΏΠΎΠ² PHP

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ PHP с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ сравнСния ΠΏΡ€ΠΈ слабых ΠΈ строгих сравнСниях. Π­Ρ‚Π° информация Ρ‚Π°ΠΊΠΆΠ΅ относится ΠΊ Ρ€Π°Π·Π΄Π΅Π»Ρƒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡŽ Ρ‚ΠΈΠΏΠΎΠ². ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π» Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² PHP Π²ΠΎΠΎΠ΄ΡƒΡˆΠΈΠ²ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° Π½Π°Π΄ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠΌ » BlueShoes.

ΠŸΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ‚Π°Π±Π»ΠΈΡ†Π°ΠΌΠΈ вспомним Π±Π°Π·ΠΎΠ²ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΈΠΏΠ°Ρ…. НаримСр, "42" β€” строка (string), Π° 42 β€” Ρ†Π΅Π»ΠΎΠ΅ число (int), false β€” логичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (bool), Π° "false" β€” строка (string).

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

HTML-Ρ„ΠΎΡ€ΠΌΡ‹ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ логичСскиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Ρ†Π΅Π»Ρ‹Π΅ ΠΈΠ»ΠΈ Π΄Ρ€ΠΎΠ±Π½Ρ‹Π΅ числа: ΠΈΠ· Ρ„ΠΎΡ€ΠΌ приходят Ρ‚ΠΎΠ»ΡŒΠΊΠΎ строки. Ѐункция is_numeric() провСряСт, относится Π»ΠΈ строка ΠΊ числовой.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

Π’Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ if ($x), Ссли ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ $x Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ, сгСнСрируСт ΠΎΡˆΠΈΠ±ΠΊΡƒ уровня E_NOTICE, поэтому ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ сначала ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ ΠΈΠ»ΠΈ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ условии ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ языковой конструкциСй empty() ΠΈΠ»ΠΈ isset().

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ арифмСтичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ прСдставляСт константа NAN (Π°Π½Π³Π». Not A Number, нСчисло). Π‘Ρ‚Ρ€ΠΎΠ³ΠΎΠ΅ ΠΈΠ»ΠΈ нСстрогоС сравнСниС Ρ‚Π°ΠΊΠΎΠ³ΠΎ значСния с Π΄Ρ€ΡƒΠ³ΠΈΠΌ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π΅Π³ΠΎ само, Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π°Ρ true, Π²Π΅Ρ€Π½Ρ‘Ρ‚ false: NAN != NAN ΠΈ NAN !== NAN. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ константу NAN: sqrt(-1), asin(2) ΠΈ acosh(0).

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠΎΠ² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ $x ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ PHP, связанных с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ
Π’Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ gettype() empty() is_null() isset() bool : if($x)
$x = ""; string true false true false
$x = null; NULL true true false false
var $x; NULL true true false false
$x Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° NULL true true false false
$x = []; array true false true false
$x = ['a', 'b']; array false false true true
$x = false; bool true false true false
$x = true; bool false false true true
$x = 1; int false false true true
$x = 42; int false false true true
$x = 0; int true false true false
$x = -1; int false false true true
$x = "1"; string false false true true
$x = "0"; string true false true false
$x = "-1"; string false false true true
$x = "php"; string false false true true
$x = "true"; string false false true true
$x = "false"; string false false true true

Π“ΠΈΠ±ΠΊΠΎΠ΅ сравнСниС Ρ‡Π΅Ρ€Π΅Π· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ==
true false 1 0 -1 "1" "0" "-1" null [] "php" ""
true true false true false true true false true false false true false
false false true false true false false true false true true false true
1 true false true false false true false false false false false false
0 false true false true false false true false true false false* false*
-1 true false false false true false false true false false false false
"1" true false true false false true false false false false false false
"0" false true false true false false true false false false false false
"-1" true false false false true false false true false false false false
null false true false true false false false false true true false true
[] false true false false false false false false true true false false
"php" true false false false* false false false false false false true false
"" false true false false* false false false false true false false true
* true Π΄ΠΎ PHP 8.0.0.

ЖёсткоС сравнСниС Ρ‡Π΅Ρ€Π΅Π· ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ===
true false 1 0 -1 "1" "0" "-1" null [] "php" ""
true true false false false false false false false false false false false
false false true false false false false false false false false false false
1 false false true false false false false false false false false false
0 false false false true false false false false false false false false
-1 false false false false true false false false false false false false
"1" false false false false false true false false false false false false
"0" false false false false false false true false false false false false
"-1" false false false false false false false true false false false false
null false false false false false false false false true false false false
[] false false false false false false false false false true false false
"php" false false false false false false false false false false true false
"" false false false false false false false false false false false true
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 8 notes

up
55
php at benizi dot com ΒΆ
16 years ago
It's interesting to note that 'empty()' and 'boolean : if($x)'
are paired as logical opposites, as are 'is_null()' and 'isset()'.
up
25
Jan ΒΆ
20 years ago
Note that php comparison is not transitive:

"php" == 0 => true
0 == null => true
null == "php" => false
up
24
frank ΒΆ
18 years ago
A comparison table for <=,<,=>,> would be nice...
Following are TRUE (tested PHP4&5):
NULL <= -1
NULL <= 0
NULL <= 1
!(NULL >= -1)
NULL >= 0
!(NULL >= 1)
That was a surprise for me (and it is not like SQL, I would like to have the option to have SQL semantics with NULL...).
up
8
blue dot hirano at gmail dot com ΒΆ
11 years ago
The truth tables really ought to be colorized; they're very hard to read as they are right now (just big arrays of TRUE and FALSE).

Also, something to consider: clustering the values which compare similarly (like is done on qntm.org/equality) would make the table easier to read as well. (This can be done simply by hand by rearranging the order of headings to bring related values closer together).
up
8
edgar at goodforall dot eu ΒΆ
16 years ago
Some function to write out your own comparisson table in tsv format. Can be easily modified to add more testcases and/or binary functions. It will test all comparables against each other with all functions. 

<?php
$funcs = array(
        /* Testing equality */
        'eq' => '==',
        'ne' => '!=',
        'gt' => '>',
        'lt' => '<',
        'ne2' => '<>',
        'lte' => '<=',
        'gte' => '>=',
        /* Testing identity */
        'id' => '===',
        'nid' => '!=='
);
class Test {
        protected $a;
        public $b;
        public function __construct($a,$b){
                $this->a = $a;
                $this->b = $b;
        }
        public function getab(){
                return $this->a.",". $this->b;
        }

}
$tst1 = new Test(1,2);
$tst2 = new Test(1,2);
$tst3 = new Test(2,2);
$tst4 = new Test(1,1);

$arr1 = array(1,2,3);
$arr2 = array(2,3,4);
$arr3 = array('a','b','c','d');
$arr4 = array('a','b','c');
$arr5 = array();

$comp1 = array(
        'ints' => array(-1,0,1,2),
        'floats' => array(-1.1,0.0,1.1,2.0),
        'string' => array('str', 'str1', '', '1'),
        'bools' => array(true, false),
        'null' => array(null),
        'objects' => array($tst1,$tst2,$tst3,$tst4),
        'arrays' => array($arr1, $arr2, $arr3, $arr4, $arr5)
);
$fbody = array();

foreach($funcs as $name => $op){
        $fbody[$name] = create_function('$a,$b', 'return $a ' . $op . ' $b;');
}

$table = array(array('function', 'comp1', 'comp2', 'f comp1 comp2', 'type'));
/* Do comparisons */
$comp2  = array();
foreach($comp1 as $type => $val){
        $comp2[$type] = $val;
}

foreach($comp1 as $key1 => $val1){
        foreach($comp2 as $key2 => $val2){
                addTableEntry($key1, $key2, $val1, $val2);
        }
}
$out = '';
foreach($table as $row){
        $out .= sprintf("%-20s\t%-20s\t%-20s\t%-20s\t%-20s\n", $row[0], $row[1], $row[2], $row[3], $row[4]);
}

print $out;
exit;

function addTableEntry($n1, $n2, $comp1, $comp2){
        global $table, $fbody;
        foreach($fbody as $fname => $func){
                        foreach($comp1 as $val1){
  foreach($comp2 as $val2){
                                        $val = $func($val1,$val2);
                                                $table[] = array($fname, gettype($val1) . ' => ' . sprintval($val1), gettype($val2) .' => ' . sprintval($val2), gettype($val) . ' => ' . sprintval($val), gettype($val1) . "-" . gettype($val2) . '-' . $fname);
                                        }
                        }
        }
}

function sprintval($val){
        if(is_object($val)){
                return 'object-' . $val->getab();
        }
        if(is_array($val)){
                return implode(',', $val);
        }
        if(is_bool($val)){
                if($val){
                        return 'true';
                }
                return 'false';
        }
        return strval($val);
}

?>
up
0
Jeroen ΒΆ
2 years ago
Be aware of the difference between checking the *value* of an array item, and checking the *existence* of an array item:
<?php
$arr = [ 
  'x' => 0,
  'y' => null,
];

isset($arr['x']); // true, same as isset(0)
isset($arr['y']); // false, same as isset(null)

array_key_exists('y', $arr); // true, though the value is null
array_key_exists('z', $arr); // false
up
2
jerryschwartz at comfortable dot com ΒΆ
20 years ago
In some languages, a boolean is promoted to an integer (with a value of 1 or -1, typically) if used in an expression with an integer. I found that PHP has it both ways:

If you add a boolean with a value of true to an integer with a value of 3, the result will be 4 (because the boolean is cast as an integer).

On the other hand, if you test a boolean with a value of true for equality with an integer with a value of three, the result will be true (because the integer is cast as a boolean).

Surprisingly, at first glance, if you use either < or > as the comparison operator the result is always false (again, because the integer as cast as a boolean, and true is neither greater nor less than true).
up
-1
mark at theanti dot social ΒΆ
8 years ago
There is also 0.0 which is not identical to 0.

  $x = 0.0; 
  gettype($x); // double
  empty($x); // true
  is_null($x); //false
  isset($x); // true
  is_numeric($x); // true
  $x ? true : false; // false
  $x == 0; // true
  $x == "0"; // true
  $x == "0.0"; // true
  $x == false; // true
  $x == null; // true
  $x === 0; // false
  $x === false; // false
  $x === null; // false
  $x === "0"; // false
  $x === "0.0"; // false