rfc:binary_string_comparison

This is an old revision of the document!


PHP RFC: Your Title Here

This RFC proposes to change the behavior of non-strict string to string comparison for equality to be binary safe.

Introduction

In PHP on comparing two strings for non-strict equality both operands will be casted to numbers and if it succeed both numbers will be compared instead of a binary string comparison.

This behavior is documented but it's very unknown and unhelpful in the wold of PHP developers and newcomers because there is no numeric context and the others knowing this behavior never use non-strict string comparison.

This behavior leads to bugs that are very hard to find and it makes code hard to know what's going on.

Proposal

This RFC proposes to change the behavior of non-strict string to string comparison for equality to be binary safe (as the strict comparison operator does).

On comparing two numeric strings both operands will be equal ONLY if the string representation will be the same.

Example (http://3v4l.org/WZq6X):

  <?php
  echo "('1'                   == '1')   = " . ('1' == '1' ? 'true' : 'false') . "\n";
  echo "('2'                   == '1')   = " . ('2' == '1' ? 'true' : 'false') . "\n";
  echo "('1e1'                 == '10')  = " . ('1e1' == '10' ? 'true' : 'false') . "\n";
  echo "('1E1'                 == '10')  = " . ('1E1' == '10' ? 'true' : 'false') . "\n";
  echo "('1e-1'                == '0.1') = " . ('1e-1' == '0.1' ? 'true' : 'false') . "\n";
  echo "('1E-1'                == '0.1') = " . ('1E-1' == '0.1' ? 'true' : 'false') . "\n";
  echo "('+1'                  == '1')   = " . ('+1' == '1' ? 'true' : 'false') . "\n";
  echo "('+0'                  == '-0')  = " . ('+0' == '-0' ? 'true' : 'false') . "\n";
  echo "('0.99999999999999994' == '1')   = " . ('0.99999999999999994' == '1' ? 'true' : 'false') . "\n";
  echo "('0.99999999999999995' == '1')   = " . ('0.99999999999999995' == '1' ? 'true' : 'false') . "\n";
  echo "(\"\\n1\"                  == '1')  = " . ("\n1" == '1' ? 'true' : 'false') . "\n";
  echo "(\"1\\n\"                  == '1')  = " . ("1\n" == '1' ? 'true' : 'false') . "\n";

Current Behavior:

  ('1' == '1')                   = true
  ('2' == '1')                   = false
  ('1e1' == '10')                = true
  ('1E1' == '10')                = true
  ('1e-1' == '0.1')              = true
  ('1E-1' == '0.1')              = true
  ('+1' == '1')                  = true
  ('+0' == '-0')                 = true
  ('0.99999999999999994' == '1') = false
  ('0.99999999999999995' == '1') = true
  ("\n1") == '1'                 = true
  ("1\n") == '1'                 = false

Changed Behavior:

  ('1' == '1')                   = true
  ('2' == '1')                   = false
  ('1e1' == '10')                = false
  ('1E1' == '10')                = false
  ('1e-1' == '0.1')              = false
  ('1E-1' == '0.1')              = false
  ('+1' == '1')                  = false
  ('+0' == '-0')                 = false
  ('0.99999999999999994' == '1') = false
  ('0.99999999999999995' == '1') = false
  ("\n1") == '1'                 = false
  ("1\n") == '1'                 = false

Backward Incompatible Changes

Existing code that relies on the current behavior will only produce the originally expected result if the string representation is the same. This can be easily resolved by explicitly casting one of the operands to an integer or float.

Proposed PHP Version(s)

As this is a backwards-incompatible change, this RFC targets PHP.next.

Open Issues

How to note behavior change? ... Is it enough to note it in the change-log or is it possible to trigger a E_DEPRECATED/E_STRICT error in PHP5.next in cases the comparison result changes in PHP.next and how to fix it.

Unaffected PHP Functionality

Only non-strict string to string comparison will be affected.

Future Scope

This sections details areas where the feature might be improved in future, but that are not currently proposed in this RFC.

Proposed Voting Choices

Voting Choices: Yes or No

This RFC requires a 2/3 majority as it changes the language itself.

Patches and Tests

Coming soon

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

None so far.

rfc/binary_string_comparison.1406844585.txt.gz · Last modified: 2017/09/22 13:28 (external edit)