code: public static function stableSort(array $data, callable $sortFn)
      {
          // Decorate each item by creating an array of [value, index]
          array_walk($data, function (&$v, $k) { $v = [$v, $k]; });
          // Sort by the sort function and use the index as a tie-breaker
          uasort($data, function ($a, $b) use ($sortFn) {
              return $sortFn($a[0], $b[0]) ?: ($a[1] < $b[1] ? -1 : 1);
          });
  
          // Undecorate each item and return the resulting sorted array
          return array_map(function ($v) { return $v[0]; }, array_values($data));
      }
docs: JMESPath requires a stable sorting algorithm, so here we'll implement
  a simple Schwartzian transform that uses array index positions as tie
  breakers.
  
  @param array    $data   List or map of data to sort
  @param callable $sortFn Callable used to sort values
  
  @return array Returns the sorted array
  @link http://en.wikipedia.org/wiki/Schwartzian_transform