7 个使用 PHP 8.5 的管道操作符的真实情景
PHP 8.5 的管道符 (|>) 是一项功能强大的新增特性,它通过清晰简洁的方式实现操作链式调用,支持更具函数式编程风格的代码编写。它取左侧表达式的结果,并将其作为第一个参数传递给右侧的函数或方法。
$value = "hello world";
$result = $value
|> function3(...)
|> function2(...)
|> function1(...);
本文将分享一些真实世界的例子,说明如何在 PHP 代码中使用管道运算符,使代码更清晰、更易读。
String cleanup in APIs
username 输入通常需要规范化。管道使该步骤可读。
$raw = " John Doe ";
$username = $raw
|> trim(...)
|> strtolower(...)
|> (fn($x) => preg_replace('/\s+/', '-', $x));
// Output: "john-doe"如你所见,此处每一步都是专注的、可测试的转换:裁剪空格→ 转换为小写 → 将空格转换成横线。
处理上传的 CSV 数据
在一个工作流中清理、验证行并将其映射到 DTO 中。
$rows = [
['name' => ' Widget A ', 'price' => '12.99', 'sku' => 'W-A'],
['name' => 'Widget B', 'price' => 'n/a', 'sku' => 'W-B'], // invalid price
['name' => 'widget c', 'price' => '7.5', 'sku' => 'W-C'],
];
// normalizeRow might trim, cast price to float, unify casing:
// ['name' => 'Widget A', 'price' => 12.99, 'sku' => 'W-A']
// ['name' => 'Widget B', 'price' => null, 'sku' => 'W-B']
// ['name' => 'Widget C', 'price' => 7.5, 'sku' => 'W-C']
// isValidRow returns false if price is null or <= 0
$products = $rows
|> (fn($xs) => array_map('normalizeRow', $xs))
|> (fn($xs) => array_filter($xs, 'isValidRow'))
|> (fn($xs) => array_map(Product::fromArray(...), $xs));
// Output: [Product('Widget A', 12.99, 'W-A'), Product('Widget C', 7.5, 'W-C')]The chain expresses a pipeline: normalization, filtering, then construction.
HTTP 响应创建
将类中间件的转换组合,以生成最终响应体。
$data = ['msg' => 'hello', 'n' => 3];
$body = $data
|> json_encode(...)
|> (fn($x) => gzencode($x, 6))
|> base64_encode(...);
// Output: H4sIAAAAAAAAA2WOuwrCMBBE…每个可调用对象都是单个参数,从而形成一个紧凑的线性构建。
搜索查询准备
在将查询发送给搜索引擎之前,对查询进行净化和标记:
$query = " Hello, WORLD! ";
$tokens = $query
|> trim(...)
|> strtolower(...)
|> (fn($x) => preg_replace('/[^\w\s]/', '', $x))
|> (fn($x) => preg_split('/\s+/', $x))
|> (fn($xs) => array_filter($xs, fn($t) => strlen($t) > 1));
// Output: ['hello', 'world']该管道将混乱的输入转化为可供搜索的索引 token。
电商购物车合计
从有折扣和税费的项目中得出总计。
// Assume helpers:
// priceAfterDiscount(['price' => 100, 'discount' => 0.10]) -> 90.0
// applyTax(90.0) with 10% tax -> 99.0
$cartItems = [
['price' => 100, 'discount' => 0.10],
];
$total = $cartItems
|> (fn($xs) => array_map('priceAfterDiscount', $xs))
|> array_sum(...)
|> (fn($sum) => applyTax($sum));
// applyTax takes one argument
// Output: 99.0步骤非常清晰:每项折扣 → 合计 → 税金;无需临时变量。
日志记录和指标充实
此管道使用时间戳、请求 ID 和 IP 充实事件,然后在记录日志之前编辑敏感字段。
$incomingEvent = [
'user' => 'alice',
'email' => 'alice@example.com'
];
$event = $incomingEvent
|> (fn($x) => array_merge($x, ['received_at' => 1696195560])) // e.g. time()
|> (fn($x) => array_merge($x, ['request_id' => '9f2a1c0b7e3d4a56'])) // example random id
|> (fn($x) => array_merge($x, ['ip' => '203.0.113.42'])) // example IP
|> (fn($x) => redactSensitive($x)); // e.g. masks email
// Output:
/*
[
'user' => 'alice',
'email' => 'a***@example.com',
'received_at' => 1696195560,
'request_id' => '9f2a1c0b7e3d4a56',
'ip' => '203.0.113.42'
]
*/图片处理链 (e.g., 缩略图)
在有些图片处理任务中,你可能需要加载图片,修改图片大小,添加水印,然后优化 web 实现。管道符可以帮你将此这些操作以清晰的方式表达出来。
$imagePath = '/images/source/beach.jpg';
$thumb = $imagePath
// GD image resource from beach.jpg
|> (fn($p) => imagecreatefromjpeg($p))
// resized to 320×240
|> (fn($im) => resizeImage($im, 320, 240))
// watermark added (e.g., bottom-right)
|> (fn($im) => applyWatermark($im))
// returns binary JPEG data or saved file path
|> (fn($im) => optimizeJpeg($im, 75));
// Output: '/images/thumbs/beach_320x240_q75.jpg'每一步都是一个单参数转换,返回下一个值,生成一个优化的缩略图。