ZetCode

PHP 太空船操作符

最后修改于 2025 年 3 月 20 日

在 PHP 7 中引入的太空船操作符 <=> 比较两个值,如果左侧小于、等于或大于右侧,则分别返回 -1、0 或 1。它简化了排序和比较,统一了数值、字符串和混合类型逻辑。本教程通过示例探讨了它的用法。

数值比较

太空船操作符提供了一个用于比较值的单一表达式,返回一个反映它们相对顺序的整数。

basic_spaceship.php
<?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)。这与 strcmpstrncmp 类似,但适用于多种类型,提供了一种简洁的替代方案,以代替多个条件语句。

按长度对字符串进行排序

该操作符擅长通过 usort 对数组进行排序,允许自定义比较,例如字符串长度,具有灵活的顺序控制。

sort_by_length.php
<?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 的行为,而无需接口。

sort_users.php
<?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 的类型比较规则,这使其对于异构数组很有用。

mixed_types.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 过滤数组,根据阈值比较选择值。

filter_spaceship.php
<?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 中链接太空船比较允许按多个条件排序,使用次要属性解决平局。

multi_sort.php
<?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 语句,用一个比较替换多个关系检查。

conditional_spaceship.php
<?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 对象,使日期比较能够用于排序或验证任务。

date_comparison.php
<?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 按值对关联数组进行排序,保留键值对以进行结构化数据。

assoc_sort.php
<?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 太空船操作符 <=>,展示了它在排序、过滤和自定义比较中的使用,并附有实际示例。

作者

我的名字是 Jan Bodnar,我是一位热情的程序员,拥有多年的编程经验。 我从 2007 年开始撰写编程文章。 到目前为止,我写了 1400 多篇文章和 8 本电子书。 我有超过八年的编程教学经验。

列出 所有 PHP 教程