PHP 函数

函数是将一段可复用代码封装起来的机制,通过函数名调用即可执行。良好的函数设计是写出高质量代码的关键——每个函数应该只做一件事,并且做好。PHP 内置了数千个函数,同时支持自定义函数,满足各种开发需求。

函数的核心价值在于代码复用逻辑封装。将重复的代码提取为函数,不仅减少了代码量,还使得修改更容易——只需改一处,所有调用点都会生效。

定义与调用函数

PHP 使用 function 关键字定义函数:

PHP 实例
function greet(string $name): string {
    return "你好,$name!欢迎学习 PHP。";
}

echo greet("张三"); // 你好,张三!欢迎学习 PHP。 echo greet("李四"); // 你好,李四!欢迎学习 PHP。 ``

PHP 函数名不区分大小写,但按照惯例应使用小驼峰命名法(getUserName)或下划线命名法(get_user_name)。

参数与默认值

函数参数可以设置默认值,调用时如果不传该参数则使用默认值:

`php function createUser( string $name, int $age = 18, string $role = 'user', bool $active = true ): string { $status = $active ? '启用' : '禁用'; return "$name($age 岁)角色:$role,状态:$status"; }

echo createUser("张三"); // 张三(18 岁)角色:user,状态:启用 echo createUser("李四", 25); // 李四(25 岁)角色:user,状态:启用 echo createUser("王五", 30, "admin"); // 王五(30 岁)角色:admin,状态:启用

// PHP 8.0+ 命名参数:可以跳过中间参数 echo createUser("赵六", role: "editor"); // 赵六(18 岁)角色:editor,状态:启用 `

注意:有默认值的参数必须放在没有默认值的参数后面。

类型声明

PHP 7+ 支持参数和返回值的类型声明,PHP 8 进一步增强了类型系统:

`php // 基本类型声明 function add(int $a, int $b): int { return $a + $b; }

// 联合类型(PHP 8.0+) function formatId(int|string $id): string { return (string)$id; }

// 可空类型 function findUser(?int $id): ?array { if ($id === null) return null; return ['id' => $id, 'name' => '张三']; }

// void 返回类型:函数不返回值 function logMessage(string $msg): void { file_put_contents('app.log', $msg . "\n", FILE_APPEND); // 不能有 return 语句(或只有空 return) }

// never 返回类型(PHP 8.1+):函数永远不正常返回 function redirect(string $url): never { header("Location: $url"); exit; } `

可变参数

使用 ... 运算符接收任意数量的参数:

`php function sum(int ...$nums): int { return array_sum($nums); }

echo sum(1, 2, 3); // 6 echo sum(1, 2, 3, 4, 5); // 15

// 混合固定参数和可变参数 function buildQuery(string $table, string ...$fields): string { $cols = implode(', ', $fields); return "SELECT $cols FROM $table"; }

echo buildQuery('users', 'id', 'name', 'email'); // SELECT id, name, email FROM users

// 展开数组作为参数 $numbers = [1, 2, 3, 4, 5]; echo sum(...$numbers); // 15 `

引用传参

默认情况下,PHP 函数参数是值传递(传入副本)。使用 & 可以传递引用,直接修改原变量:

`php function addSuffix(string &$str, string $suffix): void { $str .= $suffix; }

$title = "PHP 教程"; addSuffix($title, " - 完整版"); echo $title; // PHP 教程 - 完整版(原变量被修改)

// 对比值传递 function addSuffixByValue(string $str, string $suffix): string { return $str . $suffix; } $title2 = "PHP 教程"; $result = addSuffixByValue($title2, " - 完整版"); echo $title2; // PHP 教程(原变量不变) echo $result; // PHP 教程 - 完整版 `

匿名函数(闭包)

匿名函数没有函数名,可以赋值给变量或作为参数传递:

`php // 赋值给变量 $multiply = function(int $a, int $b): int { return $a * $b; }; echo $multiply(3, 4); // 12

// 作为回调函数 $numbers = [3, 1, 4, 1, 5, 9, 2, 6]; usort($numbers, function($a, $b) { return $a - $b; }); print_r($numbers); // [1, 1, 2, 3, 4, 5, 6, 9]

// 使用 use 捕获外部变量 $prefix = "用户:"; $format = function(string $name) use ($prefix): string { return $prefix . $name; }; echo $format("张三"); // 用户:张三

// 捕获引用(修改外部变量) $count = 0; $increment = function() use (&$count): void { $count++; }; $increment(); $increment(); echo $count; // 2 `

箭头函数(PHP 7.4+)

箭头函数是匿名函数的简写形式,自动捕获外部变量,适合简单的单行函数:

`php // 基本语法:fn(参数) => 表达式 $double = fn($n) => $n * 2; echo $double(5); // 10

// 自动捕获外部变量(不需要 use) $tax = 0.1; $withTax = fn($price) => $price * (1 + $tax); echo $withTax(100); // 110

// 在数组函数中使用 $prices = [100, 200, 300, 400, 500]; $discounted = array_map(fn($p) => $p * 0.8, $prices); $expensive = array_filter($prices, fn($p) => $p > 250); `

递归函数

函数调用自身称为递归,适合处理树形结构、分治算法等问题:

`php // 阶乘 function factorial(int $n): int { if ($n <= 1) return 1; return $n * factorial($n - 1); } echo factorial(5); // 120(5×4×3×2×1)

// 斐波那契数列 function fibonacci(int $n): int { if ($n <= 1) return $n; return fibonacci($n - 1) + fibonacci($n - 2); }

// 遍历目录树 function scanDirectory(string $dir, int $depth = 0): void { $items = scandir($dir); foreach ($items as $item) { if ($item === '.' || $item === '..') continue; echo str_repeat(' ', $depth) . $item . "\n"; $path = $dir . '/' . $item; if (is_dir($path)) { scanDirectory($path, $depth + 1); } } }

常用内置函数速查

类别函数说明
数学abs($n)绝对值
数学ceil($n)向上取整
数学floor($n)向下取整
数学round($n, $p)四舍五入
数学rand($min, $max)随机整数
数学max(...$values)最大值
数学min(...$values)最小值
字符串strlen($s)字节长度
字符串mb_strlen($s)字符长度(支持中文)
字符串str_replace($s,$r,$h)替换字符串
字符串explode($d, $s)分割字符串
字符串implode($d, $a)合并数组为字符串
数组count($a)数组长度
数组array_map($fn, $a)映射处理
数组array_filter($a, $fn)过滤数组
日期date($fmt)格式化当前时间
日期time()当前时间戳
类型isset($v)变量是否存在且非null
类型empty($v)变量是否为空
类型is_array($v)是否为数组

常见问题

Q:PHP 函数可以在定义之前调用吗? A:可以,PHP 在执行前会先扫描所有函数定义。但匿名函数赋值给变量的情况除外,变量必须先赋值才能调用。

Q:函数参数太多怎么办? A:当参数超过 3-4 个时,建议将参数封装成数组或对象传入。PHP 8 的命名参数也可以改善多参数函数的调用体验。

Q:匿名函数和箭头函数如何选择? A:单行表达式优先用箭头函数(更简洁,自动捕获变量);需要多行逻辑、或需要用 use` 控制捕获范围时用匿名函数。

Q:递归函数有什么风险? A:递归如果没有正确的终止条件,会导致无限递归,最终耗尽内存或触发 PHP 的最大嵌套深度限制(默认约 500 层)。使用递归时务必确保有明确的终止条件,并考虑用迭代替代深层递归。