PHP 函数
Defining and calling, defaults, variadics, return types, closures and arrow functions.
定义与调用
<?php
function add(int $a, int $b = 10): int {
return $a + $b;
}
echo add(1, 2), " ", add(1), "\n";
echo ADD(1, 2), "\n"; // 函数名不区分大小写
function greet(string $name): string {
return "你好,$name";
}
echo greet("Tom"), "\n";3 11
3
你好,Tom参数
<?php
// 默认值
function price(float $amount, float $rate = 0.13): float {
return $amount * (1 + $rate);
}
echo price(100), "\n"; // 113
echo price(100, 0.06), "\n"; // 106
// 命名参数(PHP 8)
echo price(rate: 0.06, amount: 200), "\n"; // 212
// 可变参数
function sum(int ...$nums): int {
return array_sum($nums);
}
echo sum(1, 2, 3, 4), "\n"; // 10
// 展开数组传参
$args = [5, 6, 7];
echo sum(...$args), "\n"; // 18
// 引用传递
function swap(int &$a, int &$b): void {
[$a, $b] = [$b, $a];
}
$x = 1; $y = 2;
swap($x, $y);
echo "$x $y\n"; // 2 1113
106
212
10
18
2 1Defaults must be constant expressions — function f($a = time()) is illegal. Pass null and fall back inside the body.
Return values
<?php
function divide(float $a, float $b): float {
if ($b == 0.0) {
throw new InvalidArgumentException("除数不能为 0");
}
return $a / $b;
}
echo divide(10, 4), "\n";
// 返回多值用数组
function minMax(array $nums): array {
return [min($nums), max($nums)];
}
[$lo, $hi] = minMax([3, 1, 4, 1, 5]);
echo "$lo $hi\n";
// 无返回值
function logMsg(string $msg): void {
echo "[LOG] $msg\n";
}
logMsg("done");2.5
1 5
[LOG] doneA function without return yields null. Declaring : void states the intent and helps static analysis.
Static variables
A static variable persists across calls and initialises only once.
<?php
function counter(): int {
static $n = 0;
return ++$n;
}
echo counter(), counter(), counter(), "\n";
function fib(int $n): int {
static $cache = [];
if ($n < 2) return $n;
return $cache[$n] ??= fib($n - 1) + fib($n - 2);
}
echo fib(30), "\n";123
832040??= (PHP 7.4) assigns only when unset — perfect for memoisation.
Closures and arrow functions
<?php
$factor = 3;
// 匿名函数必须 use 才能拿到外部变量
$mul = function ($n) use ($factor) {
return $n * $factor;
};
echo $mul(4), "\n"; // 12
// 箭头函数自动捕获(按值)
$double = fn($n) => $n * 2;
echo $double(5), "\n"; // 10
// 按引用捕获,闭包内改外部变量
$count = 0;
$inc = function () use (&$count) {
$count++;
};
$inc(); $inc();
echo $count, "\n"; // 212
10
2| Feature | function () use () | fn() => |
|---|---|---|
| Auto capture | 否,必须 use | 是 |
| Capture by reference | 支持 use (&$x) | 不支持 |
| Multi-statement body | 支持 | 只支持单个表达式 |
| Since | 5.3 | 7.4 |
Type declarations and strict mode
PHP coerces by default: passing "3" to int $a becomes 3. Add declare(strict_types=1); at the top of the file to get a TypeError instead.
<?php
declare(strict_types=1);
function twice(int $n): int {
return $n * 2;
}
echo twice(5), "\n";
try {
echo twice("5");
} catch (TypeError $e) {
echo "类型错误: " . $e->getMessage(), "\n";
}10
类型错误: twice(): Argument #1 ($n) must be of type int, string givenstrict_types applies per file and only to the calling side. A library declaring it does not make its callers strict.定义与调用
<?php
function add(int $a, int $b = 10): int {
return $a + $b;
}
echo add(1, 2), " ", add(1), "\n";
echo ADD(1, 2), "\n"; // 函数名不区分大小写
function greet(string $name): string {
return "你好,$name";
}
echo greet("Tom"), "\n";3 11
3
你好,Tomadd() 会直接 fatal error,这是引入第三方库时最常见的冲突。参数
<?php
// 默认值
function price(float $amount, float $rate = 0.13): float {
return $amount * (1 + $rate);
}
echo price(100), "\n"; // 113
echo price(100, 0.06), "\n"; // 106
// 命名参数(PHP 8)
echo price(rate: 0.06, amount: 200), "\n"; // 212
// 可变参数
function sum(int ...$nums): int {
return array_sum($nums);
}
echo sum(1, 2, 3, 4), "\n"; // 10
// 展开数组传参
$args = [5, 6, 7];
echo sum(...$args), "\n"; // 18
// 引用传递
function swap(int &$a, int &$b): void {
[$a, $b] = [$b, $a];
}
$x = 1; $y = 2;
swap($x, $y);
echo "$x $y\n"; // 2 1113
106
212
10
18
2 1默认值必须是常量表达式,不能写 function f($a = time())。需要动态默认值就传 null 再在函数体里兜底。
返回值
<?php
function divide(float $a, float $b): float {
if ($b == 0.0) {
throw new InvalidArgumentException("除数不能为 0");
}
return $a / $b;
}
echo divide(10, 4), "\n";
// 返回多值用数组
function minMax(array $nums): array {
return [min($nums), max($nums)];
}
[$lo, $hi] = minMax([3, 1, 4, 1, 5]);
echo "$lo $hi\n";
// 无返回值
function logMsg(string $msg): void {
echo "[LOG] $msg\n";
}
logMsg("done");2.5
1 5
[LOG] done不写 return 的函数返回 null。声明 : void 表示「明确不返回」,比不写更清楚,也能让静态分析工具帮你查错。
静态变量
static 变量在函数多次调用间保持值,只在第一次调用时初始化。
<?php
function counter(): int {
static $n = 0;
return ++$n;
}
echo counter(), counter(), counter(), "\n";
function fib(int $n): int {
static $cache = [];
if ($n < 2) return $n;
return $cache[$n] ??= fib($n - 1) + fib($n - 2);
}
echo fib(30), "\n";123
832040??= 是 PHP 7.4 引入的空合并赋值,$cache[$n] ??= expr 等价于「不存在才计算并写入」,用来做缓存非常顺手。
闭包与箭头函数
<?php
$factor = 3;
// 匿名函数必须 use 才能拿到外部变量
$mul = function ($n) use ($factor) {
return $n * $factor;
};
echo $mul(4), "\n"; // 12
// 箭头函数自动捕获(按值)
$double = fn($n) => $n * 2;
echo $double(5), "\n"; // 10
// 按引用捕获,闭包内改外部变量
$count = 0;
$inc = function () use (&$count) {
$count++;
};
$inc(); $inc();
echo $count, "\n"; // 212
10
2| 对比项 | function () use () | fn() => |
|---|---|---|
| 自动捕获外部变量 | 否,必须 use | 是 |
| 引用捕获 | 支持 use (&$x) | 不支持 |
| 多语句函数体 | 支持 | 只支持单个表达式 |
| 起始版本 | 5.3 | 7.4 |
类型声明与严格模式
PHP 默认是弱类型:传 "3" 给 int $a 会被自动转成 3。在文件顶部加 declare(strict_types=1); 才会抛 TypeError。
<?php
declare(strict_types=1);
function twice(int $n): int {
return $n * 2;
}
echo twice(5), "\n";
try {
echo twice("5");
} catch (TypeError $e) {
echo "类型错误: " . $e->getMessage(), "\n";
}10
类型错误: twice(): Argument #1 ($n) must be of type int, string givenstrict_types 是按文件生效的,而且只影响「调用点所在文件」。库文件声明了严格模式,不代表调用它的代码也严格——这点和很多人的直觉相反。