====== 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