0

There are some SO questions on this subject, but none of them answer it with an algorithm description, as it exists in JS (ECMAScript). It doesn't seems to exist in the PHP documentation.

I'm not a C developer and I could not even find the corresponding code in PHP sources. I will not sleep well anymore if I can't tell why (loose, ==) comparing a string/number/resource to an object/array seems to always return false?

Eg. why '' == [] is false, or why 'foo' == ['foo'] is false.

3
  • 1
    i don't know what your actually asking but: php.net/manual/en/types.comparisons.php Commented Dec 25, 2017 at 14:58
  • Thank you but it doesn't tell a clue for why '' == [] is false, or even why 'foo' == ['foo'] is false if we were presuming that an array coercion was happening. Commented Dec 25, 2017 at 16:16
  • Why was that question downvoted? This is a fundamental question about PHP understanding and there is no other question that got valuable answer. Commented Jan 11, 2018 at 11:01

2 Answers 2

3

There are multiple pages in the PHP documentation dedicated to loose comparison with the == operator. For objects, see Comparing Objects:

When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.

For loose comparison between other types, see PHP type comparison tables.

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you but it doesn't tell a clue for why '' == [] is false, or even why 'foo' == ['foo'] is false if we were presuming that an array coercion was happening.
Because one is an array and the other is a string. There is no other explanation for why. There is no coercion to array in PHP, so I don't know why we should presume that any array coercion were happening (there is, however, explicit casting to string (either by your code or by code that expects a string), which will give you the string "Array" and a stern notice), so the fact that it is false is shown in the second table I linked (array() vs "PHP").
This is an opinion (thank you for providing it anyway), not the answer I was expecting, like a link to the PHP source code in charge of the rule you are describing to me, which I agree with of course, or some part of the documentation mentioning it.
@cdoublev An array is not a string, this is not an opinion.
People making Javascript (TC39) have not the same "opinion" for '' == []. I think that when two languages doesn't have the same opinion, we can say that they establish different rules, written in specifications (like ECMAScript for JS) and in source code. I can't find the specification or the source code part for this rule in PHP.
|
2

I finally found an almost satisfying answer from this blog of a security expert (Gynvael) and by reading source code. From the former, I'm only quoting the parts that answer my initial question: why (loose, ==) comparing a string/number/resource to an object/array seems to always return false? The algorithm in charge of equivalent comparison (==) can be found here.

The main mechanics of the equality operator are implemented in the compare_function in php-src/Zend/zend_operators.c, however many cases call other functions or use big macros (which then call other functions that use even more macros), so reading this isn't too pleasant.

The operator basically works in two steps:

  1. If both operands are of a type that the compare_function knows how to compare they are compared. This behavior includes the following pairs of types (please note the equality operator is symmetrical so comparison of A vs B is the same as B vs A): • LONG vs LONG • LONG vs DOUBLE (+ symmetrical) • DOUBLE vs DOUBLE • ARRAY vs ARRAY • NULL vs NULL • NULL vs BOOL (+ symmetrical) • NULL vs OBJECT (+ symmetrical) • BOOL vs BOOL • STRING vs STRING • and OBJECT vs OBJECT

  2. In case the pair of types is not on the above list the compare_function tries to cast the operands to either the type of the second operand (in case of OBJECTs with cast_object handler), cast to BOOL (in case the second type is either NULL or BOOL), or cast to either LONG or DOUBLE in most other cases. After the cast the compare_function is rerun.

I think that all other cases return false.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.