This is an old revision of the document!
PHP RFC: Combined Comparison (Spaceship) Operator
- Version: 0.2
- Date: 2014-02-12 (original), 2015-01-19 (v0.2)
- Authors: Davey Shafik davey@php.net, Andrea Faulds ajf@ajf.me
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/combined-comparison-operator
Introduction
This RFC adds a new operator for combined comparison. Similar to strcmp()
or version_compare()
in behavior, but it can be used on all generic PHP values with the same semantics as <, <=, >=, >
.
Proposal
Add a new operator (expr) <=> (expr)
, it returns 0 if both operands are equal, 1 if the left is greater, and -1 if the right is greater.
This operator (<=>
) is often called the spaceship operator, and works on all standard PHP values. It exists in other languages: Perl, Groovy and Ruby.
For consistency with Perl, it has the same precedence as ==
and !=
.
It makes writing ordering callbacks for use with usort()
easier. Commonly, users write poor ordering functions like this:
function order_func($a, $b) { return $a >= $b; // all too common }
When users do write correct ordering functions, they have to be quite verbose:
function order_func($a, $b) { return ($a < $b) ? -1 : (($a > $b) ? 1 : 0); }
This becomes particularly bad when sorting by multiple columns lexicographically.
With this operator, you can easily write proper ordering functions, like this one:
function order_func($a, $b) { return $a <=> $b; // all too common }
It uses the existing compare_function
that underlies the other comparison operators.
// Integers echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 // Floats echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1 // Strings echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1 echo "a" <=> "aa"; // -1 echo "zz" <=> "aa"; // 1 // Arrays echo [] <=> []; // 0 echo [1, 2, 3] <=> [1, 2, 3]; // 0 echo [1, 2, 3] <=> []; // 1 echo [1, 2, 3] <=> [1, 2, 1]; // 1 echo [1, 2, 3] <=> [1, 2, 4]; // -1 // Objects $a = (object) ["a" => "b"]; $b = (object) ["a" => "b"]; echo $a <=> $b; // 0 $a = (object) ["a" => "b"]; $b = (object) ["a" => "c"]; echo $a <=> $b; // -1 $a = (object) ["a" => "c"]; $b = (object) ["a" => "b"]; echo $a <=> $b; // 1 // only values are compared $a = (object) ["a" => "b"]; $b = (object) ["b" => "b"]; echo $a <=> $b; // 0
Usort Example:
if (($handle = fopen("people.csv", "r")) !== FALSE) { while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) { $data[] = $row; } fclose($handle); } // Sort by last name: usort($data, function ($left, $right) { return $left[1] <=> $right[1]; });
Backward Incompatible Changes
This introduces no backwards incompatible changes.
Proposed PHP Version(s)
The next major version of PHP, currently PHP 7.0.
New Constants
A T_SPACESHIP
constant for use with ext/tokenizer has been added.
Unaffected PHP Functionality
All existing comparison operators, particularly <=
are unaffected by this addition.
Future Scope
None.
Proposed Voting Choices
A two third majority is required for acceptance, as it is a language change. It will be a Yes/No vote to accepting the RFC and merging.
Patches and Tests
A patch targeting php-src master is here: https://github.com/php/php-src/pull/1007
There is not yet a language specification patch.
Shafik's original patch against 5.6 was here: https://github.com/dshafik/php-src/compare/add-spaceship-operator
Changelog
- v0.2 - Updated, retargeted to PHP 7 by Andrea
- v0.1 - Initial version by Shafik