Skip to content

Commit 40514c7

Browse files
Clarify in_array() strict comparison behavior for PHP 8.0+ (#5519)
* docs: clarify in_array() strict comparison for modern PHP Update the note for the strict parameter to accurately reflect PHP 8.0.0 changes and highlight ongoing loose comparison risks with booleans. * in_array: fix the strict note and restore the unconditional advice The note said a true value in the haystack matches any non-empty string needle. Comparing a bool with a string casts the string to bool, and the two falsy strings are "" and "0", so in_array("0", [true]) is false. Say truthy instead, and add the false side of the same trap, which the removed "Similar edge cases exist for other types" sentence used to hint at. "As of PHP 8.0.0, this behavior is restricted to numeric strings" reads as if a numeric string still matched 0 in general. State the mechanism the way the manual already does on the PHP 8.0 backward incompatible changes page: the number is converted to a string and the values are compared as strings. Restore "always" on the recommendation. The previous wording, "it is recommended to", was weaker than the text it replaced, and strict does not give type safety, it selects an identity comparison. Link the loose comparison table rather than paraphrasing it, since paraphrasing it from memory is what produced the non-empty claim. Markup: &true; already expands to a constant element, so wrapping it in another one nested constant inside constant, which DocBook rejects and which is why the build was failing. Use simpara for the inline-only paragraphs, type instead of literal for the string type name, and restore the closing tag indentation. Sources - Zend/zend_operators.c, the default branch of zend_compare(), and Zend/zend_operators.h, the IS_STRING case of i_zend_is_true() - Zend/zend_operators.c, compare_long_to_string() - appendices/migration80/incompatible.xml, string to number comparison - doc-base/entities/global.ent, the true and false entities - Verified on PHP 8.5.4: in_array("0", [true]) is false, in_array("0", [false]) is true, in_array("foo", [0]) is false --------- Co-authored-by: Louis-Arnaud <la.catoire@gmail.com>
1 parent 3c1b114 commit 40514c7

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

reference/array/functions/in-array.xml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,23 @@
5454
<parameter>needle</parameter> in the <parameter>haystack</parameter>.
5555
</para>
5656
<note>
57-
<para>
58-
Prior to PHP 8.0.0, a <literal>string</literal> <parameter>needle</parameter> will match an array
59-
value of <literal>0</literal> in non-strict mode, and vice versa. That may lead to undesireable
60-
results. Similar edge cases exist for other types, as well. If not absolutely certain of the
61-
types of values involved, always use the <parameter>strict</parameter> flag to avoid unexpected behavior.
62-
</para>
57+
<simpara>
58+
Prior to PHP 8.0.0, a non-numeric <type>string</type>
59+
<parameter>needle</parameter> would loosely match a
60+
<parameter>haystack</parameter> value of <literal>0</literal>, and
61+
vice versa. As of PHP 8.0.0, the number is converted to a
62+
<type>string</type> and the two are compared as strings, so only a
63+
numeric <type>string</type> of the same value still matches.
64+
</simpara>
65+
<simpara>
66+
Non-strict mode nonetheless uses
67+
<link linkend="types.comparisions-loose">loose comparison</link>, so
68+
values of different types can still compare as equal: &true; matches
69+
any truthy <type>string</type>, and &false; matches both
70+
<literal>""</literal> and <literal>"0"</literal>. Unless the types of
71+
all values involved are known with certainty, always pass
72+
<parameter>strict</parameter> to force an identity comparison.
73+
</simpara>
6374
</note>
6475
</listitem>
6576
</varlistentry>

0 commit comments

Comments
 (0)