PHP 零基础教程

PHP 函数默认参数值

在设计 PHP 函数时,我们可以为它的参数预先设定“默认值”。如果在调用该函数时,调用者没有为该参数提供明确的值,PHP 就会自动使用这个默认值。

这个特性极大地增强了函数的灵活性,允许同一个函数在接收不同数量参数的情况下都能正常工作,从而避免了为了适应不同场景而去编写多个类似函数的麻烦(这也是 PHP 替代其他语言中“函数重载”特性的主要方式)。

1. 定义默认参数值

要为一个函数参数指定默认值,只需在函数定义的括号内,直接给参数变量赋值即可。

如果在调用函数时省略了该参数,PHP 就会使用这个默认值。如果调用时提供了值,那么提供的值就会覆盖默认值。

<?php
// 定义一个带有默认名字的问候函数
function greet($name = "游客") {
    echo "你好," . $name . "!\n";
}

// 调用函数时不提供参数
greet(); // 输出:你好,游客!

// 调用函数时提供特定参数
greet("爱丽丝"); // 输出:你好,爱丽丝!

// 定义一个计算矩形面积的函数,默认宽度为 10
function calculateRectangleArea($length, $width = 10) {
    return $length * $width;
}

// 调用函数,只提供长度,宽度将使用默认值 10
echo "面积 1:" . calculateRectangleArea(5) . "\n"; // 输出:面积 1:50 (5 * 10)

// 调用函数,同时提供长度和宽度
echo "面积 2:" . calculateRectangleArea(5, 20) . "\n"; // 输出:面积 2:100 (5 * 20)
?>

2. 【严苛规则】默认参数的排列顺序

带有默认值的参数必须放在函数签名中所有没有默认值的参数之后。

PHP 是从左到右处理参数的。如果一个没有默认值的参数跟在一个有默认值的参数后面,当调用者省略了一个值时,PHP 将无法判断究竟是哪个参数被省略了。

<?php
// 错误示范:有默认值的参数放在了无默认值参数的前面
// 这将导致一个 Parse error (解析错误):Default parameter must be declared after non-default parameters
/*
function displayUserInfo($name = "未知", $age) {
    echo "姓名:" . $name . ",年龄:" . $age . "\n";
}
*/

// 正确示范:没有默认值的参数放前面,有默认值的放后面
function displayUserInfo($age, $name = "未知") {
    echo "姓名:" . $name . ",年龄:" . $age . "\n";
}

displayUserInfo(30);        // 输出:姓名:未知,年龄:30
displayUserInfo(25, "鲍勃"); // 输出:姓名:鲍勃,年龄:25

// 你可以有多个默认参数,但它们必须全部排在最后面
function sendMessage($message, $recipient = "用户", $subject = "系统通知") {
    echo "收件人:" . $recipient . "\n";
    echo "主题:" . $subject . "\n";
    echo "正文:" . $message . "\n\n";
}

sendMessage("您的订单已发货。");
// 输出:
// 收件人:用户
// 主题:系统通知
// 正文:您的订单已发货。

sendMessage("欢迎加入!", "管理员");
// 输出:
// 收件人:管理员
// 主题:系统通知
// 正文:欢迎加入!

sendMessage("会议提醒", "开发团队", "紧急");
// 输出:
// 收件人:开发团队
// 主题:紧急
// 正文:会议提醒
?>

3. 综合实战案例

默认参数值非常适合用来创建那种“既能满足绝大多数通用场景,又允许在特殊情况下进行自定义”的灵活函数。

3.1 数据库连接函数

考虑一个用于连接数据库的函数。它通常使用标准的凭据(如 localhostroot),但有时需要连接到不同的主机或使用不同的数据库名称。

<?php
/**
 * 连接到数据库。
 *
 * @param string $host     数据库主机。默认是 'localhost'。
 * @param string $username 数据库用户名。默认是 'root'。
 * @param string $password 数据库密码。默认是空字符串 ''。
 * @param string $dbname   数据库名称。默认是 'app_db'。
 * @return string 模拟的连接状态消息。
 */
function connectToDatabase($host = 'localhost', $username = 'root', $password = '', $dbname = 'app_db') {
    // 在实际应用中,你将在这里使用 PDO 或 mysqli 来建立真实的数据库连接。
    // 为了演示,我们只返回一个字符串。
    return "正在尝试连接到 DB:$dbname (主机:$host,用户:$username)...\n" .
           "模拟连接成功。\n";
}

// 使用所有参数的默认值 (最常见的本地开发场景)
echo connectToDatabase();
// 输出:
// 正在尝试连接到 DB:app_db (主机:localhost,用户:root)...
// 模拟连接成功。

// 【高级技巧】使用 PHP 8 引入的“命名参数”跳过前面的默认值,直接修改后面的默认值
echo connectToDatabase(dbname: 'test_db'); 
// 输出:
// 正在尝试连接到 DB:test_db (主机:localhost,用户:root)...
// 模拟连接成功。

// 连接到具有特定凭据的远程主机(全部覆盖)
echo connectToDatabase('remote_server.com', 'admin_user', 'secure_pass', 'prod_db');
// 输出:
// 正在尝试连接到 DB:prod_db (主机:remote_server.com,用户:admin_user)...
// 模拟连接成功。
?>

3.2 动态生成 HTML 元素

在创建 HTML 元素生成器时,你通常希望它们带有默认的属性(比如特定的 CSS 类),但也需要保留覆盖这些属性的灵活性。

<?php
/**
 * 生成一个 HTML 按钮元素。
 *
 * @param string $text   按钮的文本内容。
 * @param string $class  按钮的 CSS 类。默认是 'btn btn-primary'。
 * @param string $type   按钮的 type 属性。默认是 'button'。
 * @param string $id     按钮的 ID 属性。默认是空字符串。
 * @return string 生成的 HTML 按钮字符串。
 */
function createButton($text, $class = 'btn btn-primary', $type = 'button', $id = '') {
    $idAttribute = $id ? " id=\"$id\"" : ""; // 只有在提供了 ID 时才添加 id 属性
    return "<button type=\"$type\" class=\"$class\"$idAttribute>$text</button>\n";
}

// 创建一个标准的 primary 按钮
echo createButton("提交表单");
// 输出: <button type="button" class="btn btn-primary">提交表单</button>

// 创建一个具有特定 ID 的警告按钮(使用 PHP 8 命名参数)
echo createButton("取消", "btn btn-warning", id: "cancelButton"); 
// 输出: <button type="button" class="btn btn-warning" id="cancelButton">取消</button>

// 创建一个具有自定义类的 submit (提交) 按钮
echo createButton("登录", "btn btn-success", "submit");
// 输出: <button type="submit" class="btn btn-success">登录</button>
?>