PHP 太空船操作符
最后修改于 2025 年 3 月 20 日
在 PHP 7 中引入的太空船操作符 <=>
比较两个值,如果左侧小于、等于或大于右侧,则分别返回 -1、0 或 1。它简化了排序和比较,统一了数值、字符串和混合类型逻辑。本教程通过示例探讨了它的用法。
数值比较
太空船操作符提供了一个用于比较值的单一表达式,返回一个反映它们相对顺序的整数。
<?php $a = 5; $b = 8; echo $a <=> $b . "\n"; echo $b <=> $a . "\n"; echo $a <=> $a . "\n";
$a <=> $b
比较 5 和 8:5 < 8,所以返回 -1。$b <=> $a
产生 1 (8 > 5),而 $a <=> $a
产生 0 (5 = 5)。这与 strcmp
或 strncmp
类似,但适用于多种类型,提供了一种简洁的替代方案,以代替多个条件语句。
按长度对字符串进行排序
该操作符擅长通过 usort
对数组进行排序,允许自定义比较,例如字符串长度,具有灵活的顺序控制。
<?php $words = ['sky', 'water', 'emotion', 'shredder', 'anonymous', 'on', 'a', 'copper', 'the', 'elephant']; usort($words, fn($e1, $e2) => strlen($e1) <=> strlen($e2)); print_r($words); usort($words, fn($e1, $e2) => strlen($e2) <=> strlen($e1)); print_r($words);
strlen($e1) <=> strlen($e2)
按升序对 $words
进行排序:从 "a" (1) 到 "anonymous" (9)。strlen($e2) <=> strlen($e1)
颠倒了排序顺序,降序排列:从 "anonymous" 到 "a"。该操作符的 -1、0、1 输出驱动 usort
,简化了自定义排序逻辑。
排序自定义对象
对于对象,当在 usort
中使用时,太空船操作符可以按属性排序,模拟类似于 Comparable
的行为,而无需接口。
<?php class User { public $fname; public $lname; public $occupation; public function __construct($fname, $lname, $occupation) { $this->fname = $fname; $this->lname = $lname; $this->occupation = $occupation; } public function __toString() { return "$this->fname $this->lname - $this->occupation"; } } $users = [ new User('John', 'Doe', 'gardener'), new User('Roger', 'Roe', 'driver'), new User('Lucia', 'Smith', 'accountant'), new User('Paul', 'Newman', 'firefighter'), new User('Adam', 'Clapton', 'teacher'), new User('Jane', 'Walter', 'pilot') ]; echo implode("\n", $users) . "\n\n"; usort($users, fn($a, $b) => $a->lname <=> $b->lname); echo implode("\n", $users) . "\n";
$a->lname <=> $b->lname
按姓氏对 $users
进行排序。排序前,它是无序的;排序后,它是 "Clapton" 到 "Walter"。该操作符以字典顺序比较字符串,使对象排序变得简单,无需正式的比较接口。
比较混合类型
太空船操作符一致地处理混合类型,应用 PHP 的类型比较规则,这使其对于异构数组很有用。
<?php $values = [5, "10", 3.14, "2"]; usort($values, fn($a, $b) => $a <=> $b); print_r($values);
$a <=> $b
对 $values
进行排序。 PHP 在可能的情况下将字符串转换为数字,因此 "2" 变为 2,"10" 变为 10,产生 [2, 3.14, 5, 10]。这展示了该操作符无缝统一类型比较的能力。
使用太空船操作符进行过滤
该操作符的数值输出可以使用 array_filter
过滤数组,根据阈值比较选择值。
<?php $numbers = [15, 7, 22, 3, 19, 10]; $threshold = 12; $above = array_filter($numbers, fn($n) => ($n <=> $threshold) > 0); print_r(array_values($above));
$n <=> $threshold > 0
保留大于 12 的数字。如果 $n <=> $threshold
为 1,则将其包含在内,结果为 [15, 22, 19]。array_values
重新索引数组。这有效地利用了该操作符的输出进行过滤逻辑。
自定义多属性排序
在 usort
中链接太空船比较允许按多个条件排序,使用次要属性解决平局。
<?php class Product { public $name; public $price; public function __construct($name, $price) { $this->name = $name; $this->price = $price; } public function __toString() { return "$this->name (\$$this->price)"; } } $products = [ new Product("Laptop", 1200), new Product("Mouse", 25), new Product("Laptop", 800), new Product("Keyboard", 50) ]; usort($products, fn($a, $b) => $a->name <=> $b->name ?: $a->price <=> $b->price ); echo implode("\n", $products) . "\n";
$a->name <=> $b->name ?: $a->price <=> $b->price
按名称排序,如果名称匹配,则按价格排序。"Laptop" 排序为 800、1200,然后是 "Keyboard" 和 "Mouse"。 PHP 类似于三元运算符的 ?:
链式比较,显示了该操作符在多级排序中的强大功能。
太空船操作符在条件逻辑中
该操作符的 -1、0、1 结果可以驱动 switch 语句,用一个比较替换多个关系检查。
<?php $x = 7; $y = 10; $result = match ($x <=> $y) { -1 => "less than", 0 => "equal to", 1 => "greater than" }; echo "$x is $result $y\n";
$x <=> $y
(7 < 10) 返回 -1,通过 match
(PHP 8+) 匹配到 "小于"。这避免了单独的 <
、==
、>
检查,使用该操作符的输出实现简洁、可读的逻辑。
比较日期
太空船操作符适用于 DateTime
对象,使日期比较能够用于排序或验证任务。
<?php $dates = [ new DateTime('2025-03-20'), new DateTime('2024-12-25'), new DateTime('2025-01-15') ]; usort($dates, fn($a, $b) => $a <=> $b); foreach ($dates as $date) { echo $date->format('Y-m-d') . "\n"; }
$a <=> $b
按时间顺序对 DateTime
对象进行排序。 PHP 的太空船操作符原生支持这一点,从 2024-12-25 到 2025-03-20 排序。这简化了日期处理,无需手动时间戳转换。
按值对关联数组进行排序
该操作符可以使用 uasort
按值对关联数组进行排序,保留键值对以进行结构化数据。
<?php $scores = [ 'Alice' => 85, 'Bob' => 92, 'Charlie' => 78, 'Dana' => 95 ]; uasort($scores, fn($a, $b) => $a <=> $b); print_r($scores);
$a <=> $b
按值对 $scores
进行排序,保留名称作为键。 它从 78 (Charlie) 到 95 (Dana) 排序。 uasort
保持关联性,并且该操作符确保数值排序,这对于排名或报告很有用。
来源
本教程介绍了 PHP 太空船操作符 <=>
,展示了它在排序、过滤和自定义比较中的使用,并附有实际示例。
作者
列出 所有 PHP 教程。