Pipe Operator 是 PHP 8.5(2025 年 11 月 20 日)中引入的一项新功能。
工作方式
管道运算符不是嵌套函数调用或创建中间变量,而是将一个表达式的结果作为第一个参数直接传递给下一个可调用对象。
传统方法
初始化
$donut = bakeDonut();
// add some toppings
第一步操作
$donut = addIcing(
bakeDonut()
);
第二步操作
$donut = addSprinkles(
addIcing(
bakeDonut()
)
);
第三步操作
$donut = addHearts(
addSprinkles(
addIcing(
bakeDonut()
)
)
);
第四步操作
$donut = addMarshmallow(
addHearts(
addSprinkles(
addIcing(
bakeDonut()
)
)
)
);
第五步操作
$donut = addChocolate(
addMarshmallow(
addHearts(
addSprinkles(
addIcing(
bakeDonut()
)
)
)
)
);
第六步操作
$donut = addCrumbs(
addChocolate(
addMarshmallow(
addHearts(
addSprinkles(
addIcing(
bakeDonut()
)
)
)
)
)
);
使用管道操作
初始化
$donut = bakeDonut();
// add some toppings
第一步操作
$donut = bakeDonut()
|> addIcing(...);
第二步操作
$donut = bakeDonut()
|> addIcing(...)
|> addSprinkles(...);
第三步操作
$donut = bakeDonut()
|> addIcing(...)
|> addSprinkles(...)
|> addHearts(...);
第四步操作
$donut = bakeDonut()
|> addIcing(...)
|> addSprinkles(...)
|> addHearts(...)
|> addMarshmallow(...);
第五步操作
$donut = bakeDonut()
|> addIcing(...)
|> addSprinkles(...)
|> addHearts(...)
|> addMarshmallow(...)
|> addChocolate(...);
第六步操作
$donut = bakeDonut()
|> addIcing(...)
|> addSprinkles(...)
|> addHearts(...)
|> addMarshmallow(...)
|> addChocolate(...)
|> addCrumbs(...);
这两个示例产生相同的结果,但管道语法改变了我们阅读和遵循代码流的方式。
传统方法显示了调用是如何嵌套的,因此迫使您从内到外解析代码。您必须首先找到 bakeDonut()
, 然后向外移动每个浇头。
管道运算符遵循自然的读取流程:从输入开始,然后按顺序执行每个步骤。这消除了匹配括号的认知开销,并使添加、删除或重新排序步骤变得微不足道。
实际例子
用户处理流水线
$adminCount = getUsers()
|> fn($users) => array_filter($users, isAdmin(...))
|> count(...);
说明
- 从系统中检索所有用户
- 将集合筛选为仅管理员用户
- 返回管理员总数
语法
- 每个可调用对象必须只接受一个必需的参数
- 数据从左到右流经管道:
A |> B |> C
- 支持任何有效的 PHP 可调用对象(函数、方法、闭包、一类可调用对象)
管道运算符与 PHP 8.1 的 first-class 可调用语法 ...:
管道运算符与 PHP 8.1 的 first-class
可调用语法 ...
:
// First-class callable syntax
$result = "hello world" |> strtoupper(...) |> trim(...);
// Works with any callable type
$data = getUsers()
|> fn($users) => array_filter($users, isAdmin(...)) // Function reference
|> array_values(...) // Built-in function
|> Processor::processUsers(...) // Static method
|> $processor->transform(...); // Instance method
...
语法在不调用函数的情况下创建可调用引用,因此它对管道链很有用。