PHP 函数

函数是把重复代码封装起来的基本单位,任何稍微大点的程序都离不开它。PHP 的函数非常灵活:支持默认参数、可变参数、类型声明、闭包、箭头函数。这一章把这些全部讲清楚。

1. 函数的基本定义

function 关键字定义函数。函数名不区分大小写(但永远保持一致),不能以数字开头:

<?php
// 定义函数
function greet($name) {
    return "你好,{$name}!";
}

// 调用
echo greet("小明");        // 你好,小明!

// 无返回值的函数(直接做事)
function sayHi($name) {
    echo "Hi, {$name}";
}
sayHi("小红");            // Hi, 小红

PHP 函数可以在文件的任意位置定义,即使调用语句在前面、定义在后面也能找到(因为 PHP 先解析整个文件再执行)。但条件定义的函数(写在 if 里)必须先定义后调用。

2. 参数:默认值、引用、可变

PHP 函数参数非常灵活,支持默认值引用传递可变长度:

<?php
// 默认参数(从右往左给)
function greet($name, $greeting = "你好") {
    return "{$greeting}, {$name}!";
}
echo greet("小明");        // 你好,小明!
echo greet("小明", "嗨");  // 嗨,小明!

// 引用参数(&):修改外部变量
function addOne(&$n) {
    $n++;
}
$count = 5;
addOne($count);
echo $count;               // 6

// 可变参数(PHP 5.6+ 用 ...)
function sum(...$nums) {
    return array_sum($nums);
}
echo sum(1, 2, 3, 4);      // 10

几个要点:

3. 类型声明与返回类型(PHP 7+)

PHP 7 起支持参数类型声明返回类型声明,让函数签名清晰、IDE 提示更好、运行更安全:

<?php
// 类型声明 + 返回类型(PHP 7+)
function add(int $a, int $b): int {
    return $a + $b;
}
echo add(2, 3);            // 5

function format(string $name, int $age): string {
    return "{$name}({$age}岁)";
}

// nullable 类型(?表示可以是 null)
function find(?int $id): ?string {
    if ($id === null) return null;
    return "user-{$id}";
}

// void:无返回值(PHP 7.1+)
function log(string $msg): void {
    error_log($msg);
}

// 联合类型(PHP 8+):可以是 int 或 float
function half(int|float $n): float {
    return $n / 2;
}

// mixed(PHP 8+):任意类型
function handle(mixed $data): mixed { /* ... */ }

支持的类型:int / float / string / bool / array / callable / iterable / object / 类名 / 接口名 / self / static / mixed / void / never。PHP 8 加入联合类型(int|float)和交集类型。

4. 严格模式 declare(strict_types=1)

默认情况下,PHP 会自动转换传入的类型(如 add(2.5, 3) 把 2.5 截成 2)。在文件第一行加 declare(strict_types=1) 后,类型不匹配会直接抛 TypeError:

<?php
declare(strict_types=1);  // 必须在文件第一行

function add(int $a, int $b): int {
    return $a + $b;
}

// 此时严格模式开启
echo add(2, 3);       // 5
// echo add(2.5, 3);   // TypeError!(严格模式不转换 float)
// echo add("2", 3);   // TypeError!(严格模式不转换 string)

// 不加 strict_types 时:PHP 会自动转换类型(弱类型)
// 加了之后:类型必须严格匹配,否则抛 TypeError

大型项目强烈建议开启严格模式,能避免大量弱类型 bug。这一行在 Symfony、Laravel 的所有源码里都能看到。

5. 匿名函数(闭包)

匿名函数是没有名字的函数,可以赋值给变量、作为参数传递。这是回调和高阶函数的基础:

<?php
// 匿名函数(闭包):没有名字的函数
$greet = function ($name) {
    return "你好,{$name}";
};
echo $greet("小明");       // 你好,小明

// use 捕获外部变量
$count = 0;
$inc = function () use (&$count) {
    $count++;
};
$inc(); $inc();
echo $count;              // 2

// 作为回调(经典用法)
$nums = [1, 2, 3, 4, 5];
$doubled = array_map(function ($n) {
    return $n * 2;
}, $nums);
print_r($doubled);        // [2, 4, 6, 8, 10]

// usort 自定义排序
usort($users, function ($a, $b) {
    return $a["age"] <=> $b["age"];
});

关键点:

6. 箭头函数 fn(PHP 7.4+)

箭头函数是更短的闭包,自动捕获外部变量,适合写单行表达式:

<?php
// 箭头函数(PHP 7.4+):更短的闭包
$double = fn($n) => $n * 2;
echo $double(5);          // 10

// 自动捕获外部变量(无需 use!)
$factor = 10;
$multiply = fn($n) => $n * $factor;
echo $multiply(5);        // 50

// 在 array_map / array_filter 里特别好用
$nums = [1, 2, 3, 4, 5];
$even = array_filter($nums, fn($n) => $n % 2 === 0);
print_r($even);           // [2, 4]

// 嵌套使用:计算所有偶数的平方和
$sum = array_sum(
    array_map(fn($n) => $n * $n,
        array_filter($nums, fn($n) => $n % 2 === 0)
    )
);

箭头函数和匿名函数的区别:

7. 可变参数、spread 与命名参数

<?php
// 可变参数 + 类型
function sum(int ...$nums): int {
    return array_sum($nums);
}
echo sum(1, 2, 3);        // 6

// spread 展开数组(调用时)
$nums = [1, 2, 3];
echo sum(...$nums);       // 6

// 命名参数(PHP 8+)
function createUser(string $name, int $age, string $role = "user") {
    // ...
}
createUser(age: 25, name: "小明");
createUser(name: "小红", role: "admin", age: 30);

命名参数是 PHP 8 的新特性,在调用函数时可以按参数名传值,顺序无关、可读性更好。配合带默认值的参数尤其方便——不用把中间的默认参数也填上。

8. 变量函数与高阶函数

小结

这一章你掌握了 PHP 函数的全部内容:定义调用、参数(默认/引用/可变)、类型声明、严格模式、闭包、箭头函数、命名参数。下一篇数组——PHP 数据处理的核心。

← 上一篇 PHP 控制流程

下一篇 PHP 数组

✈️💬