====== PHP RFC: SORT_STRICT Flag ======
* Version: 0.1
* Date: 2025-11-29
* Author: Jason Marble, jmarble@intuitivetechnology.com
* Status: Draft
===== Introduction =====
This RFC proposes ''SORT_STRICT'', a new flag that enables strict, type-aware comparison for PHP's sorting and array functions.
int(0)
// [1]=> string(0) ""
// [2]=> NULL
// [3]=> bool(false)
// [4]=> string(1) "0"
// }
?>
PHP was famously created as a loosely typed language, prioritizing flexibility and ease of use. However, the introduction of strict types in PHP 7 marked a massive paradigm shift for the language. Over the last decade, the ecosystem has matured significantly; major frameworks like Symfony and Laravel, along with modern coding standards like PER, have effectively pushed strict typing from an optional feature to a de facto standard for professional PHP development.
Despite this evolution, there is no native way to sort or filter arrays without type coercion. The ''sort()'' family defaults to ''SORT_REGULAR'' (loose equality), while ''array_unique()'' defaults to ''SORT_STRING'' (string casting), neither of which distinguishes between values of different types. This creates a friction point where modern application logic is strict, but utility functions remain loose. Currently, developers wishing to filter unique values strictly or sort mixed-type arrays deterministically must implement userspace closures using ''usort'' or specific loops. This is verbose, slower than internal C implementations, and prone to error.
===== Proposal =====
Add a new constant ''SORT_STRICT'' that can be passed to the following functions:
* **Value Sorting**: ''sort()'', ''rsort()''
* **Associative Value Sorting**: ''asort()'', ''arsort()''
* **Key Sorting**: ''ksort()'', ''krsort()''
* **Multi-Array Sorting**: ''array_multisort()''
* **Uniqueness**: ''array_unique()''
==== Comparison Logic: The "Strict Total Order" ====
''SORT_STRICT'' implements a two-step comparison:
=== Step 1: Compare Types ===
Values are first compared by their type according to this hierarchy:
NULL < Bool < Int < Float < String < Array < Object < Resource
If types differ, the comparison is decided here. No type coercion occurs.
=== Step 2: Compare Values ===
If types are identical, standard PHP comparison semantics apply:
^ Type ^ Comparison Method ^
| NULL | Always equal |
| Bool | ''false < true'' |
| Int | Numeric comparison |
| Float | Numeric comparison |
| String | Binary comparison (''strcmp'') |
| Array | Standard array comparison, with ''SORT_STRICT'' applied recursively to elements |
| Object | Standard object comparison, with ''SORT_STRICT'' applied recursively to properties |
| Resource | Resource ID comparison |
The key difference from ''SORT_REGULAR'' is that type coercion never occurs. An integer ''1'' and string ''"1"'' are never equal under ''SORT_STRICT'' because they differ at Step 1.
==== Examples ====
=== array_unique() ===
int(0)
// [1]=> string(0) ""
// }
var_dump(array_unique($values, SORT_STRICT));
// array(5) {
// [0]=> int(0)
// [1]=> string(0) ""
// [2]=> NULL
// [3]=> bool(false)
// [4]=> string(1) "0"
// }
?>
=== sort(): Order-Independent Value Matching ===
Compare arrays for identical values regardless of order:
=== sort(): Homogeneity Verification ===
Because ''SORT_STRICT'' groups values by type, sorted data has a useful property: if the first and last elements share the same type, the array is homogeneous.
===== Backward Incompatible Changes =====
None. This RFC adds a new constant and does not modify existing behavior.
===== Proposed PHP Version(s) =====
Next PHP 8.x
===== RFC Impact =====
==== To the Ecosystem ====
IDEs, static analyzers, and language servers will need to recognize the new ''SORT_STRICT'' constant. No breaking changes are expected.
==== To Existing Extensions ====
None.
==== To SAPIs ====
None.
===== Open Issues =====
None currently.
===== Future Scope =====
* A ''strict_compare($a, $b)'' function exposing the comparison logic directly
* Support for ''SORT_STRICT'' in additional array functions (e.g., ''array_diff()'', ''array_intersect()'')
===== Voting Choices =====
Primary vote requiring a 2/3 majority:
* Yes
* No
===== Patches and Tests =====
TODO: Link to implementation PR.
===== Implementation =====
TODO: After acceptance.
===== Rejected Features =====
None yet.
===== Changelog =====
* 2025-11-29: Initial draft