summaryrefslogtreecommitdiffstats
path: root/sort_recursively.php
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2021-08-09 08:03:51 +0200
committerRemi Collet <remi@remirepo.net>2021-08-09 08:03:51 +0200
commit05784e75c66f54d47e1ecc1128850cf247c7cdc9 (patch)
treec106a6734d6f220cfe15bfcabd43b56d3e44a839 /sort_recursively.php
New package
Diffstat (limited to 'sort_recursively.php')
-rw-r--r--sort_recursively.php40
1 files changed, 40 insertions, 0 deletions
diff --git a/sort_recursively.php b/sort_recursively.php
new file mode 100644
index 0000000..4d089e1
--- /dev/null
+++ b/sort_recursively.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Comparison function for custom sort. Tries to achieve a canonical sort order across PHP versions
+ * by sorting primarily by type, secondarily by value.
+ * @param mixed $a
+ * @param mixed $b
+ *
+ * @return int
+ */
+function byTypeAndValue($a, $b): int
+{
+ if (gettype($a) !== gettype($b)) {
+ return gettype($a) <=> gettype($b);
+ } else {
+ return $a <=> $b;
+ }
+}
+
+/**
+ * Sort an array by its values, recursively
+ * @param array &$array
+ */
+function sortRecursively(array &$array): void
+{
+ // Sequential array, re-index after sorting
+ if (array_keys($array) === range(0, count($array) - 1)) {
+ usort($array, 'byTypeAndValue');
+ }
+ // Associative array, maintain keys
+ else {
+ uasort($array, 'byTypeAndValue');
+ }
+
+ foreach ($array as &$value) {
+ if (is_array($value)) {
+ sortRecursively($value);
+ }
+ }
+}