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




暂无评论内容