In PHP8, you can write comparator like this for handle multiple column keys sort
<?php
class Comparator {
public static function default_comp($a, $b) {
return $a <=> $b;
}
private $comp;
public function __construct($comp = [self::class, 'default_comp']) {
$this->comp = $comp;
}
public function reverse() {
return new self(fn($a, $b) => ($this->comp)($b, $a));
}
public function column($key) {
return new self(fn($a, $b) => ($this->comp)($a[$key], $b[$key]));
}
public static function chain_impl($a, $b, ...$comp_list) {
foreach ($comp_list as $comp) {
if ($res = $comp($a, $b)) {
return $res;
}
}
return 0;
}
public function chain(...$comp_list) {
return new self(fn($a, $b) => self::chain_impl($a, $b, $this->comp, ...$comp_list));
}
public function __invoke($a, $b) {
return ($this->comp)($a, $b);
}
}
$students = array(
array('name' => 'Adam', 'score' => 90, 'grade' => 3),
array('name' => 'Bob', 'score' => 95, 'grade' => 2),
array('name' => 'Steve', 'score' => 90, 'grade' => 1),
);
$grade_comp = (new Comparator())->column('score')->reverse();
$name_comp = (new Comparator('strcmp'))->column('name');
usort($students, $grade_comp->chain($name_comp));
?>