PHP函数与参数传递
当你写了几百行代码后,会发现有些代码片段需要反复使用——这时候函数就派上用场了。函数就像一个代码容器,把常用的功能打包起来,需要的时候直接调用,不用重复写代码。
一、什么是函数?
函数是一段有名字的代码块,可以接收输入(参数),进行处理,然后返回结果。
<?php// 无参数的函数functionsayHello() {return"你好,欢迎!";}// 调用函数$message = sayHello();echo$message . "\n";// 带参数的函数functiongreet($name) { // $name 是参数return"你好," . $name . "!";}echogreet("小明") . "\n";echogreet("小红") . "\n";?>
代码讲解:
greet("小明")中"小明"是实参,调用时传的叫实参
二、参数默认值
<?php// 参数默认值functioncreateUser($name, $age = 18, $city = "北京") {return"用户信息:{$name},{$age}岁,来自{$city}";}echocreateUser("张三") . "\n"; // 使用默认年龄和城市echocreateUser("李四", 25) . "\n"; // 自定义年龄echocreateUser("王五", 30, "上海") . "\n"; // 自定义所有参数?>
代码讲解:
- 默认参数:
$age = 18表示如果没有传这个参数,就用默认值18
三、参数类型声明
PHP可以声明参数的类型,让代码更安全:
<?php// 声明参数类型functionadd(int$a, int$b): int{ // 传入整数,返回整数return$a + $b;}echoadd(10, 20) . "\n"; // 正常:输出30echoadd(3.5, 2.5) . "\n"; // PHP会自动转成3和2:输出5// 声明数组类型functionsumArray(array$numbers): float{returnarray_sum($numbers);}$nums = [1, 2, 3, 4, 5];echosumArray($nums) . "\n"; // 输出15// 联合类型(PHP 8.0+)functionprocess(string|int$value): string{return"处理值:" . $value;}echoprocess("hello") . "\n";echoprocess(123) . "\n";?>
代码讲解:
int是整数类型,float是浮点类型,string是字符串- PHP是弱类型语言,即使不声明类型也能运行,但声明类型让代码更可靠
- 联合类型
string|int表示可以是字符串或整数
四、值传递 vs 引用传递
这是非常重要的概念:
<?php// 值传递:复制一份,原变量不变functionaddFive($num) {$num += 5;echo"函数内:{$num}\n";}$a = 10;addFive($a);echo"函数外:{$a}\n"; // 仍然是10echo"\n";// 引用传递:使用&符号,原变量会被修改functionaddFiveRef(&$num) { // & 表示引用$num += 5;echo"函数内:{$num}\n";}$b = 10;addFiveRef($b);echo"函数外:{$b}\n"; // 变成15了!?>
输出结果:
函数内:15函数外:10函数内:15函数外:15
代码讲解:
- 加了
&的参数是"引用传递",函数得到的是原变量的"引用" - 引用传递适合需要"返回"多个值,或者修改外部变量的场景
五、可变数量的参数
<?php// 可变参数函数functionsum(...$numbers) { // ... 表示参数数量可变$total = 0;foreach ($numbersas$n) {$total += $n; }return$total;}echosum(1, 2, 3) . "\n"; // 输出6echosum(10, 20, 30, 40, 50) . "\n"; // 输出150// 数组展开为参数$numbers = [1, 2, 3, 4, 5];echosum(...$numbers) . "\n"; // 输出15?>
代码讲解:
...$numbers会把所有传入的参数收集到一个数组中...$numbers作为实参时,会把数组展开成一个个参数
六、匿名函数
没有名字的函数,叫匿名函数:
<?php// 匿名函数$double = function($n) {return$n * 2;};echo$double(5) . "\n"; // 输出10// 匿名函数作为参数(回调函数)$numbers = [1, 2, 3, 4, 5];$squared = array_map(function($n) {return$n * $n;}, $numbers);echo"平方后:" . implode(", ", $squared) . "\n";// 使用use捕获外部变量$multiplier = 3;$cubed = array_map(function($n) use ($multiplier) {return $n * $n * $multiplier;}, $numbers);echo"立方(乘3):" . implode(", ", $cubed) . "\n";?>
代码讲解:
array_map()是PHP的内置函数,第一个参数是回调函数,第二个是数组use ($multiplier)可以从外部捕获变量到匿名函数内部
七、箭头函数(PHP 7.4+)
更简洁的匿名函数写法:
<?php$numbers = [1, 2, 3, 4, 5];// 传统匿名函数$square1 = function($n) {return$n * $n;};// 箭头函数:fn(参数) => 表达式$square2 = fn($n) =>$n * $n;echo"平方:" . implode(", ", array_map($square2, $numbers)) . "\n";// 箭头函数更简洁的写法echo"立方:" . implode(", ", array_map(fn($n) => $n ** 3, $numbers)) . "\n";// 多参数的箭头函数$calculate = fn($a, $b, $op) =>match($op) {'+' => $a + $b,'-' => $a - $b,'*' => $a * $b,'/' => $b != 0 ? $a / $b : "错误"};echocalculate(10, 5, '*') . "\n"; // 输出50?>
八、实战:实用函数库
<?php// 验证邮箱格式functionisValidEmail($email): bool{returnfilter_var($email, FILTER_VALIDATE_EMAIL) !== false;}// 截断字符串functiontruncate($str, $length = 50, $suffix = "..."): string{if (mb_strlen($str) <= $length) {return$str; }returnmb_substr($str, 0, $length) . $suffix;}// 生成随机字符串functionrandomString($length = 16): string{$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";$str = "";for ($i = 0; $i < $length; $i++) {$str .= $chars[rand(0, strlen($chars) - 1)]; }return$str;}// 格式化日期(中文)functionformatDate($timestamp = null): string{if ($timestamp === null) {$timestamp = time(); // 当前时间 }$year = date("Y", $timestamp);$month = date("n", $timestamp);$day = date("j", $timestamp);$weekdays = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];$weekday = $weekdays[date("w", $timestamp)];return"{$year}年{$month}月{$day}日 {$weekday}";}// 测试这些函数echo"邮箱验证:\n";echoisValidEmail("test@example.com") ? "有效" : "无效";echo"\n";echoisValidEmail("not-an-email") ? "有效" : "无效";echo"\n";echo"\n字符串截断:\n";$longText = "这是一段很长的文字,需要被截断才能完整显示。";echotruncate($longText, 15) . "\n";echo"\n随机字符串:\n";echo"生成的随机密码:" . randomString(12) . "\n";echo"\n日期格式化:\n";echoformatDate() . "\n";echoformatDate(strtotime("2024-01-01")) . "\n";?>
九、写在最后
函数是代码复用和模块化的基础。学会合理地封装函数,能让你的代码更清晰、更易维护。下篇文章我们深入学习PHP数组,那是处理数据的利器。