🧠 PHP 函数从入门到精通

151 阅读2分钟

🧠 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

✅ 支持类型:

  • 标量类型(intstringboolfloat
  • 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,可以像闭包一样调用。