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 教程。