🧠 PHP 函数从入门到精通
PHP 函数是编程中最基础、也是最强大的工具之一。它不仅可以简化代码、提高复用性,还能通过各种高级用法,让你写出更灵活、更现代的代码。
下面我们从函数的基础讲起,逐步深入,带你掌握函数的核心用法和高级技巧,即使是编程小白也能轻松理解!
🧩 一、函数基础:定义与调用
函数是将一段代码封装起来,方便重复使用的代码块。
function greet($name) {echo "Hello, $name";
}greet("Tom"); // 输出:Hello, Tom
function
是定义函数的关键字$name
是参数greet("Tom")
是调用函数
📦 二、传参方式:值传参 vs 引用传参
1️⃣ 值传参(默认)
function add($a) {$a++;
}$a = 1;
add($a);
echo $a; // 输出:1
函数内部操作的是变量的副本,不会影响原始变量。
2️⃣ 引用传参(使用 &
)
function add(&$a) {$a++;
}$a = 1;
add($a);
echo $a; // 输出:2
&$a
表示传入的是变量的引用,函数内部对变量的修改会影响外部。
🎁 三、默认参数:让函数更灵活
你可以为函数参数设置默认值,这样在调用时可以省略这些参数。
function greet($name = "Guest") {echo "Hello, $name";
}greet(); // 输出:Hello, Guest
greet("Tom"); // 输出:Hello, Tom
✅ 支持类型:
- 标量类型(
int
,string
,bool
,float
) array
null
- 从 PHP 8.1 开始支持对象
class User {public function __construct(public string $name = "Guest") {}
}function greet(User $user = new User()) {echo "Hello, " . $user->name;
}greet(); // 输出:Hello, Guest
🧩 四、命名参数(PHP 8.0+)
命名参数允许你按参数名传参,跳过中间的可选参数。
function makeYogurt($container = "bowl",$flavour = "raspberry",$style = "Greek"
) {return "Making a $container of $flavour $style yogurt.\n";
}echo makeYogurt(style: "natural");
// 输出:Making a bowl of raspberry natural yogurt.
✅ 更清晰、更灵活,推荐使用。
🧮 五、可变参数(Variadic Parameters)
当函数需要接收不确定数量的参数时,可以使用可变参数语法 ...$params
。
function sum(...$nums) {return array_sum($nums);
}echo sum(1, 2, 3, 4); // 输出:10
...$nums
会把所有传入的参数收集成一个数组。- 你还可以用它来“展开”数组传参:
$values = [1, 2, 3];
echo sum(...$values); // 输出:6
✅ 可变参数与正常参数结合使用
可变参数必须是函数参数列表中的最后一个参数,前面可以有正常参数。
function logMessage($level, ...$messages) {echo "[$level] ";foreach ($messages as $msg) {echo "$msg ";}echo "\n";
}logMessage("INFO", "User", "logged", "in");
// 输出:[INFO] User logged in
🔄 六、可变函数(动态调用函数)
你可以将函数名保存在变量中,并动态调用它。
function add($a, $b) {return $a + $b;
}$func = "add";
echo $func(1, 2); // 输出:3
✅ 常用于回调、插件系统等场景。
🧩 七、实战示例:结合命名参数 + 可变参数 + 可变函数
下面是一个非常实用的综合示例,展示了三者如何结合使用:
function formatData(string $type = "json", bool $pretty = false, ...$data) {if ($pretty) {print_r($data);} else {echo json_encode($data);}
}
✅ 使用可变函数调用 + 命名参数
$formatter = 'formatData';// 使用命名参数 + 可变参数调用
$formatter(type: "json",pretty: true,"name", "age", "email"
);
📌 输出结果:
Array
([0] => name[1] => age[2] => email
)
😶🌫️ 八、匿名函数(闭包)
匿名函数是没有名字的函数,通常用于作为参数传递给其他函数,或者作为返回值。
$add = function($a, $b) {return $a + $b;
};echo $add(1, 2); // 输出:3
你还可以在闭包中使用外部变量,只需要加上 use
:
$prefix = "结果是:";
$add = function($a, $b) use ($prefix) {return $prefix . ($a + $b);
};echo $add(2, 3); // 输出:结果是:5
✅
use
可以让闭包访问它外部的变量。
🔗 bindTo:绑定闭包的上下文
有时候你想让闭包访问类的私有属性或方法,可以使用 bindTo()
:
class User {private $name = "Alice";
}$getName = function() {return $this->name;
};$user = new User();
$bound = $getName->bindTo($user, 'User');echo $bound(); // 输出:Alice
- 第一个参数是绑定的对象(
$this
) - 第二个参数是类名,表示闭包可以访问这个类的私有成员
🔄 Closure::fromCallable:将方法转为闭包
你可以把一个类的方法转换成闭包对象,这样就能像函数一样使用它:
class Greeter {private function sayHello($name) {return "Hello, $name";}
}$greeter = new Greeter();
$hello = Closure::fromCallable([$greeter, 'sayHello']);echo $hello("Tom"); // 输出:Hello, Tom
➡️ 九、箭头函数(PHP 7.4+)
箭头函数是匿名函数的简化版,写法更简洁,自动继承外部变量。
$add = fn($a, $b) => $a + $b;echo $add(1, 2); // 输出:3
它有几个特点:
- ✅ 自动继承外部变量(不需要写
use
) - ❌ 对外部变量只有读权限(不能修改)
- ✅ 只能写一行表达式(不能写多行逻辑)
🔖 十、First-class Callable(PHP 8.1+)
PHP 8.1 引入了一种新的方式,可以更方便地引用函数或方法:
$fn = strlen(...); // 获取 strlen 函数的引用
echo $fn("hello"); // 输出:5
-
...
是语法的一部分,表示你不是在调用函数,而是在引用它。 -
这种方式可以引用:
- 普通函数:
strlen(...)
- 静态方法:
Math::add(...)
- 实例方法:
$greeter->sayHello(...)
- 普通函数:
它返回的是一个 Closure
,可以像闭包一样调用。