PHP 函数详解

函数是 PHP 编程的核心组成部分,它们允许将代码组织成可重用的模块。PHP 提供了超过 1000 个内置函数,同时也支持创建自定义函数来满足特定需求。

函数概述

函数是一段封装了特定功能的可重用代码块,通过函数名来调用执行。

函数的优势:

  • 代码重用 - 避免重复编写相同代码
  • 模块化 - 将复杂问题分解为小模块
  • 可维护性 - 修改功能只需修改一处
  • 可读性 - 有意义的函数名提高代码可读性
  • 测试方便 - 可以单独测试每个函数

PHP 内置函数

PHP 提供了丰富的内置函数库,涵盖字符串处理、数组操作、数学计算、文件操作等各个方面。

字符串函数

  • strlen() - 字符串长度
  • strpos() - 查找字符串
  • substr() - 截取字符串
  • str_replace() - 字符串替换

数组函数

  • count() - 数组长度
  • array_push() - 添加元素
  • array_pop() - 删除元素
  • sort() - 数组排序

数学函数

  • abs() - 绝对值
  • round() - 四舍五入
  • rand() - 随机数
  • sqrt() - 平方根

文件函数

  • fopen() - 打开文件
  • fread() - 读取文件
  • fwrite() - 写入文件
  • file_exists() - 检查文件

如需查看所有函数的完整参考手册和实例,请访问我们的 PHP 参考手册

创建自定义函数

除了使用内置函数,PHP 还允许创建自定义函数来满足特定需求。

基本语法

function functionName() {
    // 要执行的代码
}

基础函数示例

<?php
// 定义函数
function sayHello() {
    echo "Hello World!";
}

// 调用函数
sayHello(); // 输出: Hello World!

// 带HTML的函数
function displayHeader() {
    echo "<h1>欢迎访问我的网站</h1>";
    echo "<p>这是一个示例页面</p>";
}

// 调用函数
displayHeader();
?>

个人信息函数

<?php
function writeName($fname) {
    echo $fname . " Refsnes.<br>";
}

echo "我的名字是 ";
writeName("Kai Jim");
echo "我妹妹的名字是 ";
writeName("Hege");
echo "我弟弟的名字是 ";
writeName("Stale");
?>
输出:
我的名字是 Kai Jim Refsnes.
我妹妹的名字是 Hege Refsnes.
我弟弟的名字是 Stale Refsnes.

函数参数

参数允许向函数传递数据,使函数更加灵活和通用。

单个参数

基础参数使用

<?php
function greetUser($name) {
    echo "Hello, " . $name . "!<br>";
}

greetUser("Alice");
greetUser("Bob");
greetUser("Charlie");
?>

多个参数

多参数函数

<?php
function writeName($fname, $punctuation) {
    echo $fname . " Refsnes" . $punctuation . "<br>";
}

echo "我的名字是 ";
writeName("Kai Jim", ".");
echo "我妹妹的名字是 ";
writeName("Hege", "!");
echo "我弟弟的名字是 ";
writeName("Ståle", "?");
?>

默认参数值

设置参数默认值

<?php
function createMessage($message, $type = "info") {
    echo "<div class='$type'>$message</div>";
}

createMessage("这是一条普通消息");
createMessage("这是一条成功消息", "success");
createMessage("这是一条错误消息", "error");

// 实际应用:用户问候
function welcomeUser($name, $timeOfDay = "早上") {
    echo "{$timeOfDay}好,{$name}!<br>";
}

welcomeUser("张三");
welcomeUser("李四", "下午");
welcomeUser("王五", "晚上");
?>

函数返回值

使用 return 语句可以让函数返回一个值,这个值可以在调用函数的地方使用。

基础返回值示例

<?php
function add($x, $y) {
    $total = $x + $y;
    return $total;
}

echo "1 + 16 = " . add(1, 16) . "<br>";
echo "5 + 10 = " . add(5, 10) . "<br>";

// 在表达式中使用返回值
$result = add(8, 12) * 2;
echo "计算结果: " . $result . "<br>";
?>

复杂返回值示例

<?php
// 返回数组
function getUserInfo($id) {
    $users = [
        1 => ["name" => "张三", "age" => 25, "city" => "北京"],
        2 => ["name" => "李四", "age" => 30, "city" => "上海"],
        3 => ["name" => "王五", "age" => 28, "city" => "广州"]
    ];

    return isset($users[$id]) ? $users[$id] : null;
}

$user = getUserInfo(2);
if ($user) {
    echo "姓名: " . $user['name'] . "<br>";
    echo "年龄: " . $user['age'] . "<br>";
    echo "城市: " . $user['city'] . "<br>";
}

// 返回布尔值
function isValidEmail($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

$email = "test@example.com";
if (isValidEmail($email)) {
    echo "邮箱地址有效<br>";
} else {
    echo "邮箱地址无效<br>";
}
?>

提前返回

使用条件返回

<?php
function checkAge($age) {
    if ($age < 0) {
        return "年龄不能为负数";
    }

    if ($age < 18) {
        return "未成年人";
    }

    if ($age < 60) {
        return "成年人";
    }

    return "老年人";
}

echo checkAge(15) . "<br>";  // 输出: 未成年人
echo checkAge(25) . "<br>";  // 输出: 成年人
echo checkAge(65) . "<br>";  // 输出: 老年人
?>

变量作用域

PHP 中有三种不同的变量作用域:局部、全局和静态。

局部作用域

函数内部变量

<?php
function testLocal() {
    $localVar = "我是局部变量";
    echo $localVar . "<br>";
}

testLocal();
// echo $localVar; // 错误:无法访问局部变量
?>

全局作用域

访问全局变量

<?php
$globalVar = "我是全局变量";

function testGlobal() {
    // 使用 global 关键字
    global $globalVar;
    echo $globalVar . "<br>";

    // 使用 $GLOBALS 数组
    echo $GLOBALS['globalVar'] . "<br>";
}

testGlobal();
?>

静态变量

保持值的局部变量

<?php
function testStatic() {
    static $count = 0;
    $count++;
    echo "函数被调用了 $count 次<br>";
}

testStatic(); // 输出: 函数被调用了 1 次
testStatic(); // 输出: 函数被调用了 2 次
testStatic(); // 输出: 函数被调用了 3 次
?>

高级函数特性

可变函数

通过变量调用函数

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

function sayGoodbye() {
    echo "Goodbye!<br>";
}

$functionName = "sayHello";
$functionName(); // 调用 sayHello()

$functionName = "sayGoodbye";
$functionName(); // 调用 sayGoodbye()

// 实际应用:根据用户操作调用不同函数
$action = "create";
$functions = [
    "create" => "createUser",
    "update" => "updateUser",
    "delete" => "deleteUser"
];

function createUser() { echo "创建用户<br>"; }
function updateUser() { echo "更新用户<br>"; }
function deleteUser() { echo "删除用户<br>"; }

if (isset($functions[$action])) {
    $functions[$action]();
}
?>

匿名函数

没有名称的函数

<?php
// 基础匿名函数
$greet = function($name) {
    echo "Hello, $name!<br>";
};

$greet("World");
$greet("PHP");

// 在数组函数中使用
$numbers = [1, 2, 3, 4, 5];
$squared = array_map(function($n) {
    return $n * $n;
}, $numbers);

print_r($squared);
?>

箭头函数(PHP 7.4+)

简洁的匿名函数语法

<?php
// PHP 7.4+ 箭头函数
$numbers = [1, 2, 3, 4, 5];

// 传统匿名函数
$double = array_map(function($n) {
    return $n * 2;
}, $numbers);

// 箭头函数
$triple = array_map(fn($n) => $n * 3, $numbers);

print_r($double);
echo "<br>";
print_r($triple);

// 自动捕获外部变量
$factor = 10;
$multiplied = array_map(fn($n) => $n * $factor, $numbers);
print_r($multiplied);
?>

类型声明(PHP 7+)

PHP 7 引入了标量类型声明,可以指定函数参数和返回值的类型。

参数类型声明

指定参数类型

<?php
// 标量类型声明
function addNumbers(int $a, int $b): int {
    return $a + $b;
}

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

function isActive(bool $status): string {
    return $status ? "活跃" : "非活跃";
}

echo addNumbers(5, 10) . "<br>";     // 输出: 15
echo greetUser("Alice") . "<br>";    // 输出: Hello, Alice
echo isActive(true) . "<br>";        // 输出: 活跃

// 严格模式
declare(strict_types=1);

function strictAdd(int $a, int $b): int {
    return $a + $b;
}

// strictAdd("5", 10); // 严格模式下会产生错误
?>

可空类型(PHP 7.1+)

允许返回 null 值

<?php
// 可空类型
function findUser(?string $username): ?array {
    if ($username === null) {
        return null;
    }

    // 模拟查找用户
    $users = [
        "alice" => ["name" => "Alice", "age" => 25],
        "bob" => ["name" => "Bob", "age" => 30]
    ];

    return $users[$username] ?? null;
}

$user1 = findUser("alice");
$user2 = findUser(null);

var_dump($user1);
var_dump($user2);
?>

递归函数

递归函数是调用自身的函数,常用于解决分治问题。

经典递归示例

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

echo "5! = " . factorial(5) . "<br>"; // 输出: 120
echo "10! = " . factorial(10) . "<br>"; // 输出: 3628800

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

echo "斐波那契数列: ";
for ($i = 0; $i < 10; $i++) {
    echo fibonacci($i) . " ";
}
?>

目录遍历递归

<?php
// 递归遍历目录结构
function listDirectory($path, $level = 0) {
    $indent = str_repeat("  ", $level);

    if (!is_dir($path)) {
        echo $indent . "不是目录: $path<br>";
        return;
    }

    $items = scandir($path);
    foreach ($items as $item) {
        if ($item == '.' || $item == '..') continue;

        $fullPath = $path . '/' . $item;

        if (is_dir($fullPath)) {
            echo $indent . "📁 $item<br>";
            listDirectory($fullPath, $level + 1);
        } else {
            echo $indent . "📄 $item<br>";
        }
    }
}

// 模拟目录结构
echo "目录结构示例: <br>";
listDirectory("/var/www");
?>

实际应用示例

表单验证函数

完整的表单验证系统

<?php
// 表单验证函数集合
function validateEmail($email): bool {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

function validatePassword($password): array {
    $errors = [];

    if (strlen($password) < 8) {
        $errors[] = "密码至少需要8个字符";
    }

    if (!preg_match('/[A-Z]/', $password)) {
        $errors[] = "密码必须包含至少一个大写字母";
    }

    if (!preg_match('/[a-z]/', $password)) {
        $errors[] = "密码必须包含至少一个小写字母";
    }

    if (!preg_match('/[0-9]/', $password)) {
        $errors[] = "密码必须包含至少一个数字";
    }

    return $errors;
}

function validateUsername($username): array {
    $errors = [];

    if (strlen($username) < 3) {
        $errors[] = "用户名至少需要3个字符";
    }

    if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
        $errors[] = "用户名只能包含字母、数字和下划线";
    }

    return $errors;
}

// 使用验证函数
$userData = [
    'email' => 'user@example.com',
    'username' => 'john_doe123',
    'password' => 'SecurePass123'
];

$validationErrors = [];

if (!validateEmail($userData['email'])) {
    $validationErrors[] = "邮箱地址无效";
}

$usernameErrors = validateUsername($userData['username']);
$passwordErrors = validatePassword($userData['password']);

$validationErrors = array_merge($validationErrors, $usernameErrors, $passwordErrors);

if (empty($validationErrors)) {
    echo "表单验证通过!<br>";
} else {
    echo "验证错误: <br>";
    foreach ($validationErrors as $error) {
        echo "- $error<br>";
    }
}
?>

工具函数集合

常用工具函数

<?php
// 格式化函数
function formatCurrency($amount, $currency = '¥'): string {
    return $currency . number_format($amount, 2);
}

function formatDate($date, $format = 'Y-m-d'): string {
    return date($format, strtotime($date));
}

function truncateText($text, $length = 100, $suffix = '...'): string {
    if (mb_strlen($text) <= $length) {
        return $text;
    }
    return mb_substr($text, 0, $length) . $suffix;
}

// 工具函数
function generateRandomString($length = 10): string {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';

    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }

    return $randomString;
}

function slugify($text): string {
    $text = preg_replace('~[^\pL\d]+~u', '-', $text);
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    $text = preg_replace('~[^-\w]+~', '', $text);
    $text = trim($text, '-');
    $text = preg_replace('~-+~', '-', $text);
    $text = strtolower($text);

    return $text;
}

// 使用工具函数
echo "价格: " . formatCurrency(1234.56) . "<br>";
echo "日期: " . formatDate('2023-12-25', 'Y年m月d日') . "<br>";
echo "截断文本: " . truncateText('这是一个很长的文本需要被截断显示', 10) . "<br>";
echo "随机字符串: " . generateRandomString(8) . "<br>";
echo "Slug: " . slugify('Hello World! This is a Test') . "<br>";
?>

最佳实践

函数设计最佳实践:

  • 单一职责 - 每个函数只做一件事
  • 有意义的命名 - 函数名应该清晰描述其功能
  • 保持简短 - 函数应该尽可能简短(通常不超过20行)
  • 避免副作用 - 函数应该只通过返回值与外界通信
  • 使用类型声明 - 提高代码可靠性和可读性
  • 提供文档注释 - 使用 PHPDoc 格式注释函数
  • 错误处理 - 适当的错误处理和异常抛出

良好设计的函数示例

<?php
/**
 * 计算订单总价
 *
 * @param array $items 订单项目数组
 * @param float $taxRate 税率(0-1之间)
 * @param float $discount 折扣金额
 * @return float 订单总价
 * @throws InvalidArgumentException 当参数无效时抛出异常
 */
function calculateOrderTotal(array $items, float $taxRate = 0.1, float $discount = 0): float {
    // 参数验证
    if ($taxRate < 0 || $taxRate > 1) {
        throw new InvalidArgumentException('税率必须在0-1之间');
    }

    if ($discount < 0) {
        throw new InvalidArgumentException('折扣不能为负数');
    }

    // 计算商品总价
    $subtotal = array_sum(array_column($items, 'price'));

    // 应用折扣
    $discountedTotal = max(0, $subtotal - $discount);

    // 计算税费
    $taxAmount = $discountedTotal * $taxRate;

    // 返回总价
    return $discountedTotal + $taxAmount;
}

// 使用示例
$orderItems = [
    ['name' => '商品A', 'price' => 100],
    ['name' => '商品B', 'price' => 200],
    ['name' => '商品C', 'price' => 150]
];

try {
    $total = calculateOrderTotal($orderItems, 0.1, 50);
    echo "订单总价: ¥" . number_format($total, 2) . "<br>";
} catch (InvalidArgumentException $e) {
    echo "计算错误: " . $e->getMessage() . "<br>";
}
?>

总结

  • 函数是封装可重用代码的基本单元
  • PHP 提供了丰富的内置函数库
  • 自定义函数使用 function 关键字定义
  • 参数使函数更加灵活,可以接受外部数据
  • return 语句用于从函数返回值
  • 理解变量作用域(局部、全局、静态)很重要
  • PHP 支持可变函数、匿名函数、箭头函数等高级特性
  • PHP 7+ 引入了类型声明,提高了代码可靠性
  • 递归函数适合解决分治问题
  • 遵循最佳实践可以创建高质量的函数