PHP 函数详解:定义、参数传递与最佳实践

PHP 函数详解:定义、参数传递与最佳实践

一、PHP 函数基础语法

在 PHP 中,函数是包含一组语句的块,可以在程序的不同位置多次执行。

基本定义格式

function function_name() {
    // 函数体代码
    return value;
}

核心要点:

  • 使用 function 关键字声明
  • 括号 () 接收参数
  • 花括号 {} 包裹函数体
  • return 返回结果(可选)

命名规范

// ✅ 推荐:小驼峰式或蛇形命名
function getUserProfile() { ... }      // 小驼峰
function user_profile() { ... }        // 蛇形命名
function calculateTotalPrice() { ... }  // 动作 + 名词

// ❌ 避免:单字符、保留关键字
function $data() { ... }               // 非法:$开头
function func() { ... }                // 不推荐:过于简略

二、函数参数详解

1. 必需参数

最基础的函数参数形式,调用时必须提供。

function greet($name, $message) {
    return $name . ', ' . $message;
}

echo greet('Alice', 'Hello!'); // 必须同时传递两个参数
// echo greet(); // 错误:缺少必需参数

2. 可选参数(默认值)

可以为参数设置默认值,调用时可不提供。

function introduce($name, $age = 18, $city = '未知') {
    return "$name ($age 岁) 来自 $city";
}

echo introduce('小明');     // 小明 (18 岁) 来自 未知
echo introduce('小红', 25); // 小红 (25 岁) 来自 未知
echo introduce('小白', null, '北京'); // 小白 (null 岁) 来自 北京

3. 引用传递 vs 值传递

理解参数是按值还是按引用传递非常重要。

function byValue($var) {
    $var = '新值';     // 只修改副本
}

$original = '原值';
byValue($original);
echo $original;       // 输出:原值

function byReference(&$var) {
    $var = '引用修改后'; // 直接修改变量本身
}

byReference($original);
echo $original;       // 输出:引用修改后

总结:

  • 值传递(默认):函数内修改不影响外部的变量
  • 引用传递(&):函数内修改会影响外部变量

4. 变长参数(variable functions/args)

PHP 7+ 支持灵活处理不同数量的参数。

function sum(...$numbers) {
    $result = 0;
    foreach ($numbers as $num) {
        $result += $num;
    }
    return $result;
}

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

5. 命名参数(PHP 8+)

提高代码可读性和安全性。

function createUser(string $name, int $age = 18, string $email = null) {
    return [
        'name' => $name,
        'age' => $age,
        'email' => $email ?? 'no-email@example.com'
    ];
}

$user = createUser(
    name: '张三',      // 命名参数,顺序自由
    age: 28           // 可以在任意位置添加
);

三、函数返回值详解

1. 基本 return

function add(int $a, int $b): int {
    return $a + $b;      // 返回计算结果
}

echo add(5, 3);         // 输出:8
$result = add(2, 2);    // 返回值存入变量,输出:4

2. 多个返回值(PHP 7.2+)

function divide(int $num1, int $num2): array {
    if ($num2 == 0) {
        throw new Exception('除数不能为 0');
    }
    return [
        'quotient' => $num1 / $num2,
        'remainder' => $num1 % $num2
    ];
}

$result = divide(7, 3);
echo $result['quotient'];     // 输出:2.333...
echo $result['remainder'];    // 输出:1

3. void(不返回值)

function logError($message) {
    error_log($message);     // 写入错误日志
    return;                  // 或省略 return
}

logError('Something went wrong');  // 没有实际返回值
// $result = logError('test');     // null

四、函数作用域

1. 局部变量与全局变量

$global_var = '我是全局变量';

function testGlobal() {
    echo $global_var;           // ❌ 非法:直接访问非法

    global $global_var;         // ✅ 引用全局变量
    echo $global_var;           // 输出:我是全局变量
}

testGlobal();

2. 静态属性

函数内部可以使用 static 声明静态变量,其值在函数调用之间保持。

function counter() {
    static $count = 0;          // 首次调用时初始化为 0

    echo "当前计数:$count\n";
    $count++;
}

counter(); // 输出:当前计数:0
counter(); // 输出:当前计数:1
counter(); // 输出:当前计数:2

应用场景: 全局计数器、状态机等。

3. 使用静态方法代替全局变量(推荐)

// ❌ 不推荐:全局变量污染命名空间
global $user_count;

// ✅ 推荐:类静态属性
class UserService {
    private static $userCount = 0;

    public static function addUser() {
        self::$userCount++;
    }
}

UserService::addUser();

五、内置函数与自定义函数

PHP 内置函数示例

函数 作用 示例
echo 输出(非函数,关键字) echo 'Hello';
print 输出并返回值 1 $x = print "test";
var_dump() 显示变量类型和值 var_dump($age);
print_r() 打印数组/对象 print_r($arr);
array_map() 映射函数到数组 array_map('strtolower', $arr);
array_filter() 过滤数组 array_filter($arr, function($v){return $v>0;});
usort() / uasort() 排序自定义比较器 usort($list, 'cmp');

使用内置函数创建高级功能

// 链式过滤和映射
$numbers = [1, 2, 3, 4, 5];
$squaredEvens = array_filter(
    array_map(fn($n) => $n * $n, $numbers),
    fn($v) => $v % 2 == 0
);

echo implode(',', $squaredEvens); // 输出:4,16,36,64

六、最佳实践与性能优化

1. 使用类型声明(PHP 7+)

提高代码安全性和可读性。

// ❌ 不推荐:没有类型约束
function processData($input) { ... }

// ✅ 推荐:明确类型定义
function processData(string $data, int $length): array {
    // 函数接受字符串,返回数组
}

2. 使用晚绑定(Late Static Binding)

class ParentClass {
    public static function test(): string {
        return static::getName(); // 使用 late binding
    }

    private static $name = 'Parent';
}

class ChildClass extends ParentClass {
    private static $name = 'Child';
}

echo ChildClass::test(); // 输出:Child

3. 使用不可变对象(PHP 8+ readonly)

readonly class Config {
    public function __construct(
        public string $app_name,
        public int $max_connections = 100
    ) {}
}

// Config::setConfig(new Config('myApp')); // 编译错误

4. 避免在循环中重复创建函数

// ❌ 不推荐:循环内重新定义函数
for ($i = 0; $i < 10; $i++) {
    function calculate($x) { return $i * $x; } // 每次覆盖前一次
}

// ✅ 推荐:使用闭包或类方法
$multipliers = [];
for ($i = 0; $i < 10; $i++) {
    $multipliers[] = function($x) use ($i) { 
        return $i * $x; 
    };
}

5. 合理使用匿名函数命名参数

// ✅ 推荐:闭包时显式声明参数名称
$closure = function(int $x): int {
    return $x * 2;
};

七、常见陷阱与调试技巧

1. "未定义变量"错误

function test($undefinedVar) { ... } // ❌ 可能报错
function test($undefinedVar = null) { ... } // ✅ 提供默认值
defined('CONFIG_VALUE') or CONFIG_VALUE = 'default'; // ⚠️ PHP 8+ 不推荐写法

2. 引用导致意外修改

function modify(&$array) {
    array_push($array, 'new item');
}

$items = ['a', 'b'];
modify($items);           // $items 已变为 ['a', 'b', 'new item']

解决: 明确需要引用时使用 &,否则避免。

3. 变量作用域混淆

function complexScope() {
    global $globalVar;       // 引用全局
    static $staticVar = 0;   // 静态局部

    if (isset($local)) {     // 局部变量
        echo "使用局部: $local";
    } else {
        echo "未定义:$local"; // 会触发警告!
    }
}

complexScope();              // ✅ 输出:未定义:

4. 调试函数推荐

// 查看当前函数所有变量
get_defined_vars();          // 获取当前作用域所有变量

// 查看函数调用栈
debug_backtrace();           // 显示调用链

// 性能分析
function timedOperation() {
    $start = microtime(true);
    // ... 代码 ...
    $end = microtime(true);
    echo sprintf('耗时:%.4f 秒', $end - $start);
}

八、总结与对比表

特性 说明 推荐用法
参数传递 值传递默认,引用需 & function($x) / function(&$x)
返回值 可使用多返回值(数组) [ 'a' => 1, 'b' => 2 ]
作用域 global/static/local 优先使用参数传递和静态属性
类型声明 PHP 7+ 强烈推荐 function add(int $x, int $y): int
命名参数 PHP 8+ 特性 func(name: 'value')
变长参数 PHP 7+ 支持 function(...$args)

参考资料

  • PHP Manual – Functions
  • PHP 8 新特性:类型声明、命名参数、readonly
  • PSR-12 代码规范:函数定义与格式要求

写作时间: 2026 年 5 月 20 日
难度等级: 初级到中级
推荐阅读顺序: 掌握变量基础后继续学习函数

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容