PHP 函数:自定义函数、参数、返回值、匿名函数、箭头函数
PHP 函数概述
函数是一段可以重复调用的代码块,把重复的逻辑封装成函数,避免代码重复,提高可维护性。
一、自定义函数
基本定义
<?php\nfunction sayHello() {\n echo "你好!";\n}\n\n// 调用\nsayHello();\n\n// 带参数\nfunction greet(string $name) {\n echo "你好,{$name}!";\n}\ngreet("张三"); // 你好,张三!\n?>
返回值
<?php\nfunction add(int $a, int $b): int {\n return $a + $b;\n}\n\n$result = add(3, 5);\necho $result; // 8\n\n// 返回多个值(用数组)\nfunction getUser() {\n return ['name' => '张三', 'age' => 25];\n}\n$user = getUser();\necho $user['name'];\n\n// 早期 PHP 返回多个值\nfunction divide($a, $b) {\n if ($b == 0) return false;\n return [$a / $b, $a % $b]; // 商和余数\n}\n?>
二、参数类型约束
<?php\n// PHP 7+ 支持严格类型约束\ndeclare(strict_types=1);\n\nfunction add(int $a, int $b): int {\n return $a + $b;\n}\n\nadd(5, 3); // 正常\nadd("5", "3"); // PHP 8 前自动转换,PHP 8 报 TypeError\n\n// 多种类型约束\nfunction process(string|array $data): string|array {\n if (is_array($data)) {\n return implode(',', $data);\n }\n return strtoupper($data);\n}\n\n// 对象类型约束\nfunction render(Renderable $obj) {\n echo $obj->render();\n}\n?>
三、参数默认值
<?php\nfunction createUser(string $name, int $age = 18, string $city = '未知') {\n echo "{$name},{$age}岁,来自{$city}";\n}\n\ncreateUser("张三"); // 张三,18岁,来自未知\ncreateUser("李四", 25); // 李四,25岁,来自未知\ncreateUser("王五", 30, "绍兴"); // 王五,30岁,来自绍兴\n\n// 注意:有默认值的参数放后面\n// 错误:function test($a = 1, $b) {}\n// 正确:function test($b, $a = 1) {}\n?>
四、可变参数列表
func_get_args()(旧方式)
<?php\nfunction sum() {\n $total = 0;\n foreach (func_get_args() as $n) {\n $total += $n;\n }\n return $total;\n}\necho sum(1, 2, 3, 4, 5); // 15\n?>
... 展开运算符(PHP 8+,推荐)
<?php\nfunction sum(...$numbers): int {\n return array_sum($numbers);\n}\necho sum(1, 2, 3, 4, 5); // 15\n\n// 固定参数 + 可变参数\nfunction connect(string $host, string $user, string $pass, ...$options) {\n echo "连接 {$host},用户 {$user}\\n";\n print_r($options);\n}\nconnect('localhost', 'root', '123', 'port'=>3306, 'charset'=>'utf8mb4');\n\n// 数组展开传入\n$numbers = [1, 2, 3, 4, 5];\necho sum(...$numbers); // 15,等于 sum(1,2,3,4,5)\n?>
五、命名参数(PHP 8+)
<?php\nfunction createUser(string $name, int $age = 18, string $city = '未知') {\n echo "{$name},{$age}岁,来自{$city}\\n";\n}\n\n// 旧方式:按位置传参\ncreateUser("张三", 25, "绍兴");\n\n// PHP 8 命名参数:可以只指定部分参数\ncreateUser(name: "李四", city: "杭州");\ncreateUser("王五", city: "宁波", age: 30);\n?>
六、匿名函数(闭包)
<?php\n// 匿名函数(没有名字的函数)\n$double = function(int $n): int {\n return $n * 2;\n};\necho $double(5); // 10\n\n// 回调函数中使用\n$numbers = [1, 2, 3, 4, 5];\n$result = array_map(function($n) {\n return $n * $n;\n}, $numbers);\nprint_r($result); // [1, 4, 9, 16, 25]\n\n// 用 use 捕获外部变量\n$multiplier = 3;\n$numbers = [1, 2, 3];\n$result = array_map(function($n) use ($multiplier) {\n return $n * $multiplier;\n}, $numbers);\nprint_r($result); // [3, 6, 9]\n?>
七、箭头函数(PHP 7.4+)
箭头函数是匿名函数的简写,适合单行返回表达式:
<?php\n// 箭头函数(自动捕获父作用域变量)\n$numbers = [1, 2, 3, 4, 5];\n\n// 旧写法\n$result = array_map(function($n) use ($multiplier) {\n return $n * $multiplier;\n}, $numbers);\n\n// 箭头函数写法(更简洁)\n$multiplier = 3;\n$result = array_map(fn($n) => $n * $multiplier, $numbers);\n// 自动捕获 $multiplier,不需要 use\n\n// 箭头函数只支持单行表达式,不能有语句\n$sum = fn(...$nums) => array_sum($nums);\necho $sum(1, 2, 3, 4, 5); // 15\n?>
八、回调函数类型
<?php\n// 回调函数类型声明\nfunction apply(array $items, callable $callback): array {\n $result = [];\n foreach ($items as $item) {\n $result[] = $callback($item);\n }\n return $result;\n}\n\n$numbers = [1, 2, 3, 4, 5];\n$result = apply($numbers, fn($n) => $n * $n);\nprint_r($result);\n\n// Closure 类型\nfunction once(callable $callback): Closure {\n // 包装为只执行一次的函数\n}\n?>
九、函数返回值类型
<?php\ndeclare(strict_types=1);\n\n// 声明返回值类型\nfunction getConfig(): array {\n return ['host' => 'localhost'];\n}\n\nfunction getName(): string {\n return "张三";\n}\n\n// void 无返回值\nfunction log(string $msg): void {\n file_put_contents('log.txt', $msg . "\\n");\n}\n\n// 联合返回类型\nfunction parse($input): string|array {\n if (is_array($input)) return $input;\n return strval($input);\n}\n\n// never(PHP 8.1+,永不返回)\nfunction fail(string $msg): never {\n throw new Exception($msg);\n}\n?>
十、递归函数
<?php\n// 阶乘\nfunction factorial(int $n): int {\n if ($n <= 1) return 1;\n return $n * factorial($n - 1);\n}\necho factorial(5); // 120 = 5*4*3*2*1\n\n// 目录遍历\nfunction scanDir(string $path, int $depth = 0): array {\n $result = [];\n $items = scandir($path);\n foreach ($items as $item) {\n if ($item === '.' || $item === '..') continue;\n $fullPath = $path . '/' . $item;\n $result[] = str_repeat(' ', $depth) . $item;\n if (is_dir($fullPath)) {\n $result = array_merge($result, scanDir($fullPath, $depth + 1));\n }\n }\n return $result;\n}\n?>
总结
- 函数用
function关键字定义,参数和返回值都可以声明类型 ...可变参数适合参数数量不固定的场景- 匿名函数
function(){}用于回调,箭头函数fn() => expr更简洁 - 箭头函数自动捕获父作用域变量,不需要
use - 命名参数(PHP 8+)让调用更清晰,可跳过有默认值的参数
declare(strict_types=1)开启严格类型检查