1 | For more information, tests and examples see this post: | http://gynvael.coldwind.pl/?id=492 | (note: this table totally ignores proxy objects) | by Gynvael Coldwind (2013-01-01) | ||||||
---|---|---|---|---|---|---|---|---|---|---|
2 | op1 → op2 ↓ | NULL | BOOL | LONG | DOUBLE | STRING | ARRAY | OBJECT | RESOURCE | |
3 | NULL | always equal | if op1 is FALSE then equal | equal if op1 is 0 | equal if op1 evaluates as false in C | converts NULL to STRING "" calls zend_binary_strcmp | equal if array is empty | always not equal | equal if op1 numeric value is 0 | |
4 | BOOL | if op2 is FALSE then equal | equal if (LONG)op1-(LONG)op2 is 0 | op1 is converted to BOOL like this: if op1 is 0, then FALSE else TRUE then it's compared with op2 | op1 is converted to BOOL like this: if op1 evaluates as true in C, it's TRUE else it's FALSE then it's compared with op2 | op1 is converted to BOOL like this: if op1 is exactly "0" or empty string, it's FALSE else it's true then it's compared with op2 | op1 is converted to BOOL like this: if array is empty, it's FALSE else it's TRUE then it's compared with op2 | if op1 has cast_object*, then it's cast to BOOL; on failure to cast; it's unequal on success, it's compares as BOOL vs BOOL in case of no cast_object: op2 is cast to LONG, op1 is cast to LONG(1) and a LONG vs LONG comparison is done *standard php object will cast object to BOOL(true) | op1 is converted to BOOL like this: if op1 value is 0, then FALSE else TRUE then it's compared with op2 | |
5 | LONG | equal if op2 is 0 | op2 is converted to BOOL like this: if op2 is 0, then FALSE else TRUE then it's compared with op1 | if not op1>op2 and not op1<op2 then equal | op2 is cast to DOUBLE then compared with op1 | op1 is converted to LONG or DOUBLE or to LONG(0) if conversion fails then it's compared: - either LONG vs LONG or - op2 is cast to DOUBLE, and it's compared DOUBLE vs DOUBLE | always not equal | if op1 has cast_object*, then it's cast to LONG; on failure to cast; it's unequal on success, it's compares as LONG vs LONG in case of no cast_object: op1 is cast to LONG(1) and a LONG vs LONG comparison is done *standard php object will cast object to LONG(1) but issue an E_NOTICE | op1 numerical value is used as LONG standard LONG vs LONG comparision follows | |
6 | DOUBLE | equal if op2 evaluates as false in C | op2 is converted to BOOL like this: if op2 evaluates as true in C, it's TRUE else it's FALSE then it's compared with op1 | op1 is cast to DOUBLE then compared with op1 | equal if op1 == op2 | op1 is converted to LONG or DOUBLE or to LONG(0) if conversion fails then it's compared: - either DOUBLE vs DOUBLE or - it's cast to DOUBLE, and it's compared DOUBLE vs DOUBLE | always not equal | if op1 has cast_object*, then it's cast to DOUBLE; on failure to cast; it's unequal on success, it's compares as DOUBLE vs DOUBLE in case of no cast_object: op1 is cast to LONG(1), op2 is cast to LONG and a LONG vs LONG comparison is done *standard php object will cast object to DOUBLE(1.0) but issue an E_NOTICE | op1 numerical value is used as a LONG standard LONG vs DOUBLE comparison follows | |
7 | STRING | converts NULL to STRING "" calls zend_binary_strcmp | op2 is converted to BOOL like this: if op2 is exactly "0" or empty string, it's FALSE else it's true then it's compared with op1 | op2 is converted to LONG or DOUBLE or to LONG(0) if conversion fails then it's compared: - either LONG vs LONG or - op1 is cast to DOUBLE, and it's compared DOUBLE vs DOUBLE | op2 is converted to LONG or DOUBLE or to LONG(0) if conversion fails then it's compared: - either DOUBLE vs DOUBLE or - it's cast to DOUBLE, and it's compared DOUBLE vs DOUBLE | tries to convert both strings into LONG or DOUBLE using is_numeric_string; if successful with no overflows: - compares LONG vs LONG or - compares DOUBLE vs DOUBLE - casts LONG to DOUBLE and compares DOUBLE vs DOUBLE otherwise it falls back to string comparison (equal on exact match) | always not equal | if op1 has cast_object*, then it's cast to string; on failure to case, it's unequal on success, a standard STRING vs STRING comparison is done in case no cast_object, op1 is cast to LONG(1), op2 is cast to LONG using is_numeric_string, or, in case of failure, it's cast to LONG(0) a LONG vs LONG comparison is done *standard php object will call __tostring PHP method if it exists, or return FAILURE if __tostring returns non-string, a recoverable error is raised, but still the cast succeds returning empty STRING; a STRING vs STRING comparison follows | op2 is converted to LONG or DOUBLE using is_numeric_string, or to LONG 0 if conversion fails; op1 numerical value is used as LONG; then comparision is made same as in DOUBLE vs DOUBLE or LONG vs DOUBLE | |
8 | ARRAY | equal if array is empty | op2 is converted to BOOL like this: if array is empty, it's FALSE else it's true then it's compared with op1 | always not equal | always not equal | always not equal | to be equal: keys must match to the byte, but values are deeply compared using ALL THIS again | if op1 has cast_object*, then it's cast to ARRAY; on failure to cast; it's unequal on success, it's compares as ARRAY vs ARRAY in case of no cast_object: always unequal *standard php object will FAIL to cast to ARRAY | always not equal | |
9 | OBJECT | always not equal | if op2 has cast_object*, then it's cast to BOOL; on failure to cast; it's unequal on success, it's compares as BOOL vs BOOL in case of no cast_object: op1 is cast to LONG, op2 is cast to LONG(1) and a LONG vs LONG comparison is done *standard php object will cast object to BOOL(true) | if op2 has cast_object*, then it's cast to LONG; on failure to cast; it's unequal on success, it's compares as LONG vs LONG in case of no cast_object: op2 is cast to LONG(1) and a LONG vs LONG comparison is done *standard php object will cast object to LONG(1) but issue an E_NOTICE | if op2 has cast_object*, then it's cast to DOUBLE; on failure to cast; it's unequal on success, it's compares as DOUBLE vs DOUBLE in case of no cast_object: op2 is cast to LONG(1), op1 is cast to LONG and a LONG vs LONG comparison is done *standard php object will cast object to DOUBLE(1.0) but issue an E_NOTICE | if op2 has cast_object*, then it's cast to string; on failure to case, it's unequal on success, a standard STRING vs STRING comparison is done in case no cast_object, op2 is cast to LONG(1), op1 is cast to LONG using is_numeric_string, or, in case of failure, it's cast to LONG(0) a LONG vs LONG comparison is done *standard php object will call __tostring PHP method if it exists, or return FAILURE if __tostring returns non-string, a recoverable error is raised, but still the cast succeds returning empty STRING; a STRING vs STRING comparison follows | if op2 has cast_object*, then it's cast to ARRAY; on failure to cast; it's unequal on success, it's compares as ARRAY vs ARRAY in case of no cast_object: always unequal *standard php object will FAIL to cast to ARRAY | if objects have the same compare handler: - if it's the same object, equal - else call the compare handler (all this again) **else (in PHP 5.4.6): try to convert both objects using cast_object to LONG if no cast_object or it fails, object is converted to LONG(1) then compare objects as LONGs NOTE: DO NOT USE **else (in PHP 5.4.10): return not equal NOTE: OK | if op2 has cast_object*, then it's cast to RESOURCE; on failure to cast; it's unequal on success, it casts both op1 and op2 to LONG and does a LONG vs LONG comparison in case of no cast_object: op1 is cast to LONG, op2 is cast to LONG(1), and a LONG vs LONG comparison is done *standard php object will FAIL to cast to RESOURCE | |
10 | RESOURCE | equal if op2 numeric value is 0 | op2 is converted to BOOL like this: if op2 value is 0, then FALSE else TRUE then it's compared with op1 | op2 numerical value is used as LONG standard LONG vs LONG comparision follows | op2 numerical value is used as a LONG standard LONG vs DOUBLE comparison follows | op1 is converted to LONG or DOUBLE using is_numeric_string, or to LONG 0 if conversion fails; op2 numerical value is used as LONG; then comparision is made same as in DOUBLE vs DOUBLE or LONG vs DOUBLE | always not equal | if op1 has cast_object*, then it's cast to RESOURCE; on failure to cast; it's unequal on success, it casts both op1 and op2 to LONG and does a LONG vs LONG comparison in case of no cast_object: op2 is cast to LONG, op1 is cast to LONG(1), and a LONG vs LONG comparison is done *standard php object will FAIL to cast to RESOURCE | op1 and op2 numerical values are compared as LONGs (specific subtypes are ignored, but this doesn't matter since the values are unique id's anyway) |