跳到主要内容

PHP 函数

本章将介绍 PHP 函数的定义、参数、返回值以及高级特性。

函数基础

函数是一段可重复使用的代码块,用于执行特定任务。

定义函数

使用 function 关键字定义函数:

<?php
function greet() {
echo "Hello, World!";
}

greet(); // 调用函数,输出:Hello, World!
?>

函数命名规则

  1. 函数名以字母或下划线开头
  2. 只能包含字母、数字、下划线
  3. 函数名不区分大小写(但建议保持一致)
  4. 不能使用 PHP 保留字
<?php
function sayHello() {
echo "Hello!";
}

sayhello(); // 有效,但不推荐
SAYHELLO(); // 有效,但不推荐
sayHello(); // 推荐
?>

参数

位置参数

<?php
function greet($name) {
echo "Hello, $name!";
}

greet("张三"); // 输出:Hello, 张三!
?>

默认参数

<?php
function greet($name, $greeting = "Hello") {
echo "$greeting, $name!";
}

greet("张三"); // 输出:Hello, 张三!
greet("张三", "你好"); // 输出:你好, 张三!
?>

默认参数必须放在参数列表的末尾:

<?php
// 正确
function correct($a, $b = 2, $c = 3) {
return $a + $b + $c;
}

// 错误:默认参数后不能有非默认参数
// function wrong($a = 1, $b, $c = 3) {
// return $a + $b + $c;
// }
?>

类型声明

PHP 7+ 支持参数类型声明:

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

echo add(1, 2); // 输出:3

// 严格模式下,类型不匹配会报错
declare(strict_types=1);

function multiply(int $a, int $b): int {
return $a * $b;
}

// multiply(1.5, 2); // 严格模式下会报错
?>

支持的类型声明:

  • int - 整数
  • float - 浮点数
  • string - 字符串
  • bool - 布尔值
  • array - 数组
  • object - 对象
  • callable - 可调用
  • iterable - 可迭代
  • ClassName - 类名
  • ?Type - 可空类型(PHP 7.1+)
<?php
// 可空类型
function greet(?string $name): string {
return $name ?? "Guest";
}

echo greet(null); // 输出:Guest
echo greet("张三"); // 输出:张三
?>

可变参数

func_get_args()

<?php
function sum() {
$total = 0;
foreach (func_get_args() as $num) {
$total += $num;
}
return $total;
}

echo sum(1, 2, 3, 4, 5); // 输出:15
?>

... 运算符(PHP 5.6+)

<?php
function sum(...$numbers) {
return array_sum($numbers);
}

echo sum(1, 2, 3, 4, 5); // 输出:15

// 也可以传递数组
$nums = [1, 2, 3];
echo sum(...$nums); // 输出:6
?>

类型声明的可变参数

<?php
function sum(int ...$numbers): int {
return array_sum($numbers);
}

echo sum(1, 2, 3); // 输出:6
?>

命名参数(PHP 8.0+)

<?php
function createUser($name, $age = 18, $city = "北京") {
return [
"name" => $name,
"age" => $age,
"city" => $city
];
}

// 传统调用
$user1 = createUser("张三", 25, "上海");

// 命名参数(可以跳过默认参数)
$user2 = createUser(name: "李四", city: "广州");
$user3 = createUser(city: "深圳", name: "王五", age: 30);
?>

返回值

return 语句

<?php
function add($a, $b) {
return $a + $b;
}

$result = add(1, 2);
echo $result; // 输出:3
?>

返回类型声明

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

function greet(string $name): string {
return "Hello, $name";
}

function getItems(): array {
return [1, 2, 3];
}
?>

可空返回类型

<?php
function findUser(int $id): ?string {
$users = [1 => "张三", 2 => "李四"];
return $users[$id] ?? null;
}

echo findUser(1); // 输出:张三
var_dump(findUser(3)); // 输出:NULL
?>

void 返回类型(PHP 7.1+)

<?php
function logMessage(string $message): void {
echo "[" . date("Y-m-d H:i:s") . "] $message\n";
}

logMessage("系统启动"); // 输出带时间戳的日志
?>

混合返回类型(PHP 8.0+)

<?php
function getValue($input): mixed {
if (is_numeric($input)) {
return $input + 0;
}
return $input;
}

var_dump(getValue("123")); // int(123)
var_dump(getValue("hello")); // string(5) "hello"
?>

永不返回(PHP 8.1+)

<?php
function throwError(string $message): never {
throw new Exception($message);
}

function redirect(string $url): never {
header("Location: $url");
exit();
}
?>

变量作用域

局部变量

函数内部声明的变量是局部变量:

<?php
$x = 10; // 全局变量

function test() {
$x = 20; // 局部变量
echo "函数内:$x\n";
}

test(); // 输出:函数内:20
echo "函数外:$x"; // 输出:函数外:10
?>

global 关键字

在函数内部访问全局变量:

<?php
$x = 10;
$y = 20;

function add() {
global $x, $y;
return $x + $y;
}

echo add(); // 输出:30
?>

$GLOBALS 数组

<?php
$x = 10;
$y = 20;

function add() {
return $GLOBALS['x'] + $GLOBALS['y'];
}

echo add(); // 输出:30
?>

静态变量

<?php
function counter() {
static $count = 0;
$count++;
return $count;
}

echo counter(); // 1
echo counter(); // 2
echo counter(); // 3
?>

匿名函数与闭包

匿名函数

<?php
$greet = function($name) {
return "Hello, $name!";
};

echo $greet("张三"); // 输出:Hello, 张三!
?>

闭包

闭包可以捕获外部变量:

<?php
$message = "Hello";

$greet = function($name) use ($message) {
return "$message, $name!";
};

echo $greet("张三"); // 输出:Hello, 张三!
?>

按引用捕获:

<?php
$count = 0;

$increment = function() use (&$count) {
$count++;
};

$increment();
$increment();
echo $count; // 输出:2
?>

箭头函数(PHP 7.4+)

箭头函数是更简洁的匿名函数语法:

<?php
// 传统匿名函数
$add = function($a, $b) {
return $a + $b;
};

// 箭头函数
$add = fn($a, $b) => $a + $b;

echo $add(1, 2); // 输出:3
?>

箭头函数自动捕获外部变量:

<?php
$multiplier = 10;

// 传统方式需要 use
$multiply = function($n) use ($multiplier) {
return $n * $multiplier;
};

// 箭头函数自动捕获
$multiply = fn($n) => $n * $multiplier;

echo $multiply(5); // 输出:50
?>

回调函数

使用 callable 类型

<?php
function processArray(array $arr, callable $callback): array {
$result = [];
foreach ($arr as $item) {
$result[] = $callback($item);
}
return $result;
}

$numbers = [1, 2, 3, 4, 5];

// 使用匿名函数
$squares = processArray($numbers, function($n) {
return $n * $n;
});

// 使用箭头函数
$doubled = processArray($numbers, fn($n) => $n * 2);

print_r($squares); // [1, 4, 9, 16, 25]
print_r($doubled); // [2, 4, 6, 8, 10]
?>

内置回调函数

<?php
$numbers = [1, 2, 3, 4, 5];

// array_map
$squares = array_map(fn($n) => $n * $n, $numbers);

// array_filter
$evens = array_filter($numbers, fn($n) => $n % 2 == 0);

// array_reduce
$sum = array_reduce($numbers, fn($carry, $n) => $carry + $n, 0);

// usort
$users = [
["name" => "张三", "age" => 25],
["name" => "李四", "age" => 20],
["name" => "王五", "age" => 30]
];

usort($users, fn($a, $b) => $a["age"] <=> $b["age"]);
?>

高级特性

引用传递

默认情况下,参数是值传递。使用 & 可以引用传递:

<?php
function increment(&$num) {
$num++;
}

$count = 5;
increment($count);
echo $count; // 输出:6
?>

引用返回

<?php
$items = [];

function &getItem($index) {
global $items;
return $items[$index];
}

$items[0] = "初始值";
$item = &getItem(0);
$item = "新值";

echo $items[0]; // 输出:新值
?>

可变函数

使用变量调用函数:

<?php
function sayHello() {
echo "Hello!";
}

function sayGoodbye() {
echo "Goodbye!";
}

$func = "sayHello";
$func(); // 输出:Hello!

$func = "sayGoodbye";
$func(); // 输出:Goodbye!
?>

First-class callable 语法(PHP 8.1+)

<?php
function add($a, $b) {
return $a + $b;
}

// 传统方式
$callable = 'add';

// 新语法
$callable = add(...);

echo $callable(1, 2); // 输出:3
?>

递归函数

函数调用自身:

<?php
// 计算阶乘
function factorial($n) {
if ($n <= 1) {
return 1;
}
return $n * factorial($n - 1);
}

echo factorial(5); // 输出:120

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

echo fibonacci(10); // 输出:55
?>

小结

本章我们学习了:

  1. 函数的定义和调用
  2. 参数传递:位置参数、默认参数、类型声明、可变参数
  3. 返回值和返回类型声明
  4. 变量作用域:局部变量、全局变量、静态变量
  5. 匿名函数、闭包和箭头函数
  6. 回调函数的使用
  7. 高级特性:引用传递、可变函数、递归

下一章我们将学习数组的详细操作。