.

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)

.

op1 →
op2
NULLBOOLLONGDOUBLESTRINGARRAYOBJECTRESOURCE

.

NULLalways equalif op1 is FALSE then equalequal if op1 is 0equal if op1 evaluates as false in Cconverts NULL to STRING ""
calls zend_binary_strcmp
equal if array is emptyalways not equalequal if op1 numeric value is 0

.

BOOLif op2 is FALSE then equalequal if (LONG)op1-(LONG)op2 is 0op1 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

.

LONGequal if op2 is 0op2 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 equalif 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

.

DOUBLEequal if op2 evaluates as false in Cop2 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 == op2op1 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 equalif 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

.

STRINGconverts 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 equalif 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

.

ARRAYequal if array is emptyop2 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 equalalways not equalalways not equalto be equal: keys must match to the byte, but values are deeply compared using ALL THIS againif 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

.

OBJECTalways not equalif 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

.

RESOURCEequal if op2 numeric value is 0op2 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 equalif 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)