It's interesting to note that 'empty()' and 'boolean : if($x)'
are paired as logical opposites, as are 'is_null()' and 'isset()'.
다음 테이블은 PHP 자료형 과 느슨한 비교와 엄격한 비교를 위한 비교 연산자의 동작을 설명한다. 이 부록은 자료형 조절에 관한 매뉴얼 섹션과도 관련이 있다. 다양한 유저 주석과 » BlueShoes의 보고서를 통해 영감을 얻을수 있다.
이 테이블을 이용하기 전에, 자료형과 각 자료형의 의미를 이해해야 한다. 예를 들면,
"42"는 string형이고,
반면에 42는 integer형이다.
FALSE
는 boolean형이고, "false"는
string형이 되는것이다.
Note:
HTML 폼은 정수, 부동소수점, 논리형으로 전달하지 않는다. 문자열형으로 전달한다. 문자열이 숫자값인지 확인하기 위해서는 is_numeric()를 사용할수 있다.
Note:
$x가 선언되지 않았는데 단순히 if ($x)를 수행하면
E_NOTICE
레벨의 에러가 발생할것이다. 대신 empty()나 isset()을 사용하고 그 변수를 초기화시키도록 한다.
Expression | gettype() | empty() | is_null() | isset() | boolean : if($x) |
---|---|---|---|---|---|
$x = ""; | string | TRUE |
FALSE |
TRUE |
FALSE |
$x = null; | NULL | TRUE |
TRUE |
FALSE |
FALSE |
var $x; | NULL | TRUE |
TRUE |
FALSE |
FALSE |
$x is undefined | NULL | TRUE |
TRUE |
FALSE |
FALSE |
$x = array(); | array | TRUE |
FALSE |
TRUE |
FALSE |
$x = false; | boolean | TRUE |
FALSE |
TRUE |
FALSE |
$x = true; | boolean | FALSE |
FALSE |
TRUE |
TRUE |
$x = 1; | integer | FALSE |
FALSE |
TRUE |
TRUE |
$x = 42; | integer | FALSE |
FALSE |
TRUE |
TRUE |
$x = 0; | integer | TRUE |
FALSE |
TRUE |
FALSE |
$x = -1; | integer | 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 |
array() | "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 |
TRUE |
TRUE |
-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 |
array() | FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
FALSE |
FALSE |
TRUE |
TRUE |
FALSE |
FALSE |
"php" | TRUE |
FALSE |
FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
FALSE |
FALSE |
TRUE |
FALSE |
"" | FALSE |
TRUE |
FALSE |
TRUE |
FALSE |
FALSE |
FALSE |
FALSE |
TRUE |
FALSE |
FALSE |
TRUE |
TRUE |
FALSE |
1 | 0 | -1 | "1" | "0" | "-1" | NULL |
array() | "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 |
array() | 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 |
It's interesting to note that 'empty()' and 'boolean : if($x)'
are paired as logical opposites, as are 'is_null()' and 'isset()'.
Note that php comparison is not transitive:
"php" == 0 => true
0 == null => true
null == "php" => false
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...).
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).
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);
}
?>
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
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
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).