php可通过array_map、array_filter等函数实践函数式编程,强调不可变性、纯函数与声明式表达,虽无原生不可变数组,但能通过约定和封装模拟,兼顾实用性与函数式思想。

PHP 数组本身不是函数式编程的原生载体,但借助其丰富的内置数组函数(如 array_map、array_filter、array_reduce 等)和匿名函数支持,完全可以实践函数式编程的核心思想:不可变性、纯函数、高阶函数、声明式表达。
用纯函数处理数组,避免副作用
纯函数指相同输入始终返回相同输出,且不修改外部状态或输入数据。PHP 中操作数组时,默认多数函数(如 sort()、array_push())会直接修改原数组 —— 这违背函数式原则。应优先选用返回新数组的函数:
-
array_map($callback, $arr):对每个元素应用回调,返回新数组,原数组不变 -
array_filter($arr, $callback):筛选元素,返回符合条件的新数组 -
array_reduce($arr, $callback, $initial):归约计算,返回单个值(如求和、拼接、嵌套结构扁平化)
例如,将用户数组中所有名字转为大写并过滤掉空名:
php$users = [['name' => 'alice'], ['name' => ''], ['name' => 'bob']];
$upperNames = array_map(fn($u) => ['name' => strtoupper($u['name'])], $users);
$validNames = array_filter($upperNames, fn($u) => !empty($u['name']));
// $users 未被修改,$upperNames 和 $validNames 是全新数组
?>
组合高阶函数,实现声明式逻辑
函数式编程强调“做什么”,而非“怎么做”。通过链式组合高阶函数(PHP 8.0+ 支持更自然的链式写法,或用变量临时承接),可清晰表达业务意图:
立即学习“PHP免费学习笔记(深入)”;
一个功能强大的B2B与B2C的购物平台,除了原本OSC功能外,增加更新的功能: 一、 取消了register_globals必须开启的限制 二、 將HTML程式碼与PHP程式碼完全分离,採用了smarty 樣板引擎 三、 每支档案includes所需函数与资料库连结,使的网页显示速度明显提升 四、 检视、购买商品群组权限设定 五、 十八岁以下禁购机制 六、 折价券购物抵扣机制 七、 礼券购物机制
- 避免嵌套
foreach+ 手动if+push的命令式写法 - 把转换、筛选、聚合等步骤拆解为独立、可复用、可测试的小函数
- 利用闭包捕获上下文(如配置、阈值),保持函数纯度
示例:统计活跃用户中各城市人数(假设 $users 是关联数组):
array_filter($users, fn($u) => $u['status'] === 'active'),
fn($carry, $user) => [
$user['city'] => ($carry[$user['city']] ?? 0) + 1
],
[]
);
?>
模拟不可变数组与结构共享
PHP 没有原生不可变数组,但可通过约定和封装降低风险:
- 始终用
array_*函数返回新数组,不调用sort()、unset()等修改原数组的函数 - 对深层嵌套结构更新,使用递归 +
array_replace_recursive或自定义withXxx()辅助函数 - 结合类型系统(PHP 8+ 类型声明 + Psalm/PHPStan)约束参数为
array,避免意外传入对象或资源
例如安全地更新用户地址中的邮编:
$updateZip = fn(array $user, string $newZip) => ['id' => $user['id'],
'name' => $user['name'],
'address' => [
'street' => $user['address']['street'] ?? '',
'zip' => $newZip
]
];
$updated = $updateZip($user, '10001'); // 原 $user 不变
?>
注意 PHP 的实际限制与取舍
完全函数式在 PHP 中是“风格借鉴”而非范式迁移。需清醒面对现实:
- 性能敏感场景(如超大数组循环),
foreach仍比array_map快;必要时可混合使用 - 调试时,链式调用不如分步变量直观;适当拆解、命名中间结果提升可读性
- PHP 的引用机制(
&$arr)与函数式理念冲突,尽量避免在函数参数中使用引用传递数组 - 第三方库(如 Laravel Collections)提供了更流畅的函数式链式 API,可作为补充










