函数
1.函数的定义与调用
1.初识函数
在编程语言中,函数是封装一段用于完成特定功能的代码。当使用一个函数时,只需关心函数的参数和返回值,就可以完成一个特定的功能。下面通过一段代码来演示函数的作用。
<?php$str = 'AbCd';$upper = strtoupper($str);$lower = strtolower($str);echo $upper; //输出ABCDecho $lower; //输出abcd?>
在上述代码中,strtoupper()和strtolower()是PHP内置的函数,用于对字符串进行大小写转换。如果PHP没有提供这两个函数,那么开发人员就要手动编写代码来实现上述工作。由此可见,使用函数可以方便程序的开发和维护。
除了使用PHP的内置函数,开发人员还可以自己定义一些函数,来将程序代码模块化,提高代码的可复用性。
<?phpfunction general_table($row,$col){$html = '<table border="1" cellspacing="0" width=500px height=300px>';for ($i=1; $i <=$row ; ++$i) {$html .= '<tr>';for ($j=1; $j <=$col ; ++$j) {$html .= '<td></td>';}$html .='</tr>';}return $html.'</table>';}echo general_table(3,4); //生成3行4列的表格echo general_table(5,6); //生成5行6列的表格?>
在初步了解了函数的定义与使用之后,下面我们具体看一下函数定义的语法结构。
function 函数名([参数1,参数2,......]){函数体......}
从上述语法格式可以看出,函数的定义由关键字function、函数名、参数和函数体4部分组成。关于这4部分的相关说明如下。
- function:在声明函数时必须使用的关键字。
- 函数名:函数名称的定义要符合PHP的标识符,且函数名是唯一的,不区分大小写。
- [参数1, 参数2…]:外界传递给函数的值,它是可选的,多个参数之间使用逗号“,”分隔。
- 函数体:函数定义的主体,专门用于实现特定功能的代码段。若想要得到一个处理结果,即函数的返回值,需要使用return关键字将需要返回的数据传递给调用者。
2.参数设置
对于函数来说,参数的不同设置,决定了其调用和使用方式。在对函数定义的语法格式有所了解后,接下来分别介绍几种常用的函数定义与调用方式,具体如下。
1.无参函数
function shout(){return 'come on';}echo shout(); //输出结果:come on
2.按值传递参数
PHP默认支持按值传递参数,按此种方式定义的函数,在函数内部可以随意对用户传递的参数进行操作,具体示例如下。
<?phpfunction add($a,$b){$a = $a + $b;return $a;}echo add(5,7); //输出12?>
对于有参数的函数在调用时,不仅可以如示例中一样直接传值,还可以使用变量代替。具体如下。
<?phpfunction add($a,$b){$a = $a + $b;return $a;}$x = 5;$y = 7;echo add($x,$y); //输出12?>
3.引用传参
<?phpfunction extra(&$str){$str .= ' and some extra';}$var = 'food';extra($var);echo $var; //输出:food and some extra?>
在上述示例中,将函数的参数设置为引用传参后,如果函数内修改了参数var的值将会跟着变化。
4.设置参数默认值
函数参数在设置时,还可以为其指定默认值,也就是可选参数。当调用者未传递该参数时,函数将使用默认值进行操作。具体示例如下。
<?phpfunction say($p,$con = 'say "hello"'){return "$p $con";}echo say('Tom'); //输出:Tom say "hello"?>
需要注意的是,在为函数参数设置默认值时,默认(可选)参数必须放在非默认(必选)参数的右侧,且默认值必须是常量表达式,如“123”“PHP”等。否则,函数将不会按照预期的情况工作。
5.指定参数类型
在PHP 7.0及以上的版本后,在自定义函数时,可以指定参数具体是哪种数据类型,示例如下。
<?phpfunction sum1(int $a,int $b){return $a + $b;}echo sum1(2.6,3.8); //输出结果:5?>
从上述示例可知,当用户调用函数时,如果传递的参数不是int类型,程序会将其强制转换为int型后再进行操作,这种方式称为弱类型参数设置。
除此之外,还可以将其设置为强类型的参数,即当用户传递的参数类型不符合函数的定义,程序会报错提醒。具体代码如下。
<?phpdeclare(strict_types = 1);function sum2(int $a,int $b){return $a + $b;}echo sum2(2.6,3.8); //输出结果:Fatal error: ......?>
3.变量的作用域
变量只有在其作用范围内才可以被使用,这个作用范围称为变量的作用域。在函数中定义的变量称为局部变量,在函数外定义的变量称为全局变量,具体如下所示。
<?phpfunction test(){$sum = 36; //局部变量return $sum;}$sum = 0; //全局变量echo test(); //输出结果:36echo $sum; //输出结果:0?>
需要注意的是,默认情况下在函数中不能使用全局变量,同时局部变量的改变也不会对全局变量有任何影响,如示例中的$sum。
那么如何在函数中使用全局变量呢?PHP提供了3种方式,分别为参数传递、global关键字和超全局变量$GLOBALS。其中,参数传递的方式前面已经讲解过了,这里不再演示。其他两种方式的具体使用方式下所示。
<?phpfunction test(){//方法1:利用global关键字取得全局变量global $var;echo '全局变量$var:'.$var.'<br>'; //输出:全局变量$var:100//方法2:利$GLOBALS['变量名']访问echo '全局变量$str:'.$GLOBALS['str']; //输出:全局变量$str:php}$var = 100;$str = 'php';test();?>
从上述代码可以看出,若要在函数内使用全局变量,在使用前要么通过global关键字取得后再使用;要么使用“$GLOBALS[‘变量名’]”的方式才可以访问。
2.函数的嵌套调用
1.嵌套调用
函数的嵌套调用,指的是在调用一个函数的过程中,调用另外一个函数,这种在函数内调用其他函数的方式称为嵌套调用。例如,班主任老师要计算每个学生语文和数学平均分,其实现思路是首先编写一个函数用于计算学生的语文和数学的总分,然后再编写一个函数用于计算学生的平均分,具体如例如下。
<?phpfunction sum($sub1,$sub2){return $sub1 + $sub2;}function avg($sub1,$sub2){$sum = sum($sub1,$sub2);return $sum / 2;}echo '学生A平均成绩:'.avg(50,60); //输出:学生A平均成绩:55echo '<br>';echo '学生B平均成绩:'.avg(70,80); //输出:学生B平均成绩:75?>
程序执行流程:
①程序开始执行,调用avg()函数,并传递参数sub2。
②在avg()函数中,调用sum()函数并传递参数sub2,进入sum()函数,计算总分将结果返回到函数avg()中,同时将值赋给变量$sum。
③avg()函数接着根据sum()函数返回的值,完成平均分的计算并将结果返回。
④输出平均分,程序结束
2.递归调用
递归调用是函数嵌套调用中一种特殊的调用。它指的是一个函数在其函数体内调用自身的过程,这种函数称为递归函数。
<?phpfunction factorial($n){if ($n == 1)return 1;return $n * factorial($n - 1);}echo factorial(4); //输出:24?>
上述代码中定义了一个递归函数factorial(),用于实现n的阶乘计算。当n乘以factorial(
%EF%BC%8C%E7%9B%B4%E5%88%B0#card=math&code=n-1%29%EF%BC%8C%E7%9B%B4%E5%88%B0)n等于1时,返回1。由此,可以得到图3-3所示的执行流程。

图3-3描述了factorial()函数的递归调用全部过程。其中,factorial()函数被调用了4次,并且每次调用时,n的值为1时,所有递归调用的函数都会以相反的顺序相继结束,所有的返回值相乘,最终得到的结果为24。
3.函数的高级应用
1.静态变量
我们知道在函数中定义的变量,在函数执行完成后会被释放。例如,定义一个计数的函数num(),具体如下所示。
<?phpfunction num(){$i = 1;echo $i;++$i;}?>
从上述示例可知,不论调用多少次num()函数,输出的i赋值为1。因此,若想要局部变量在函数执行完成后,依然保留局部变量的值,则可以利用static关键字在函数中声明静态变量。将上述示例中的第3行代码修改成如下形式。
static $i = 1;
修改完成后。第1次调用函数num()输出1,第2次调用函数num()会输出2,依次类推,就可以轻松得到num()函数被调用的次数,使函数中定义的变量不会在函数调用完成后被释放掉,保存了每次调用函数时改变的值。
2.可变函数
前面我们学习了可变变量,它的实现是在一个变量前添加一个“$”符号,就变成了另外一个变量。同理,可变函数的实现就是在一个变量名后添加一对圆括号“()”,让其变成一个函数的形式,然后PHP就寻找与变量值同名的函数,并且尝试执行它,具体如例3-4所示。
<?phpfunction shout(){echo 'come on......';}$funcname = 'shout'; //定义变量,其值是函数名称echo $funcname(); //利用可变变量调用函数,输出:come on......?>
在上述代码中,变量funcname()的方式进行调用,最后在浏览器中输出“come on….”。
在实际编程中,使用可变函数可以增加程序的灵活性,但是滥用可变函数会降低PHP代码的可读性,使程序逻辑难以理解,给代码的维护带来不便,所以在编程过程中要尽量少用可变函数。
3.回调函数
回调函数(callback)指的就是具有callable类型的函数,一般用作参数的传递。如PHP内置函数call_user_func()可以接受用户自定义的回调函数作为参数,如下所示。
<?phpfunction sum($a,$b){return $a + $b;}echo call_user_func('sum',4,5); //输出结果:9?>
在上述示例中,call_user_func()函数的第1个参数表示callable类型的回调函数名称,如sum()函数。第2个和第3个参数表示向回调函数传递的参数,如4和5。因此,程序执行函数call_user_func()后,将调用sum()函数并返回执行结果。
4.匿名函数
匿名函数就是没有函数名称的函数,也称作闭包函数,经常用作回调函数参数的值。对于临时定义的函数,使用匿名函数无需考虑函数命名冲突的问题,具体示例如下所示。
<?php$sum = function($a,$b){ //定义匿名函数return $a + $b;};echo $sum(100,200); //输出:300?>
在上述代码中,定义一个匿名函数,并赋值给变量$sum,然后通过“变量名()”的方式调用匿名函数。需要注意的是,此种匿名函数调用的方式看似与可变函数的使用类似,但实际上不是,若通过var_dump()对匿名函数的变量进行打印输出,可以看到其数据类型为对象类型。
在开发中,若要在匿名函数中使用外部的变量,需要通过use关键字实现,具体使用示例如下。
<?php$c = 100;$sum = function($a,$b) use($c){ //定义匿名函数return $a + $b + $c;};echo $sum(100,200); //输出:400?>
在上述代码中,若要在匿名函数中使用外部变量,该变量需先在函数声明前进行定义。然后在定义匿名函数时,添加use关键字,其后圆括号“()”中的内容即为要使用的外部变量列表,多个变量之间使用英文逗号“,”分隔即可。
除此之外,匿名函数还可以作为函数的参数传递,实现回调函数,具体使用示例如下。

在上述代码中,calculate()函数的第3个参数$func是一个回调函数,通过这种方式,可以将函数的一部分处理交给调用时传递的另一个函数,极大增强了函数的灵活性。
4.PHP的内置函数
对于常用的功能,除了自定义函数外,PHP还提供了许多内置函数。例如,针对字符串的截取、替换等操作PHP专门提供了对应的函数,针对数据的求和、平均数等操作提供了对应的数学函数以及获取时间日期的函数等。
1.字符串函数
| 函数名称 | 参数 | 功能描述 |
|---|---|---|
| strlen() | 获取字符串的长度 | |
| strpos() | 查找字符串首次出现的位置 | |
| strrpos() | 计算指定字符串在目标字符串中最后一次出现的位置 | |
| str_replace() | 子字符串替换 | |
| substr() | 返回字符串的子串 | |
| explode() | 使用一个字符串分割另一个字符串 | |
| implode() | 用指定的连接符将数组拼接成一个字符串 | |
| trim() | 去除字符串首尾处的空白字符(或者其他字符) | |
| str_repeat() | 重复一个字符串 | |
| strcmp() | 用于判断两个字符串大小 |
2.数学函数
| 函数名 | 功能描述 |
|---|---|
| abs() | 取绝对值 |
| ceil() | 向上取最接近的整数 |
| floor() | 向下取最接近的整数 |
| fmod() | 取除法的浮点数余数 |
| is_nan() | 判断是否为合法数值 |
| max() | 取最大值 |
| min() | 取最小值 |
| pi() | 取圆周率的值 |
| pow() | 计算x的y次方 |
| sqrt() | 取平方根 |
| round() | 对浮点数进行四舍五入 |
| rand() | 生成随机整数 |
3.时间日期函数
在使用PHP开发Web应用程序时,经常会涉及日期和时间管理。例如,倒计时、用户登录时间、新闻发布时间、购买商品时下订单的时间等。为此,PHP提供了内置的日期和时间处理函数,满足开发中的各种需求。
| 函数名 | 功能描述 |
|---|---|
| time() | 取得当前的UNIX时间戳 |
| date() | 格式化一个本地时间/日期 |
| mktime() | 获取指定日期的UNIX时间戳 |
| strtotime() | 将字符串转化成UNIX时间戳 |
| microtime() | 获取当前UNIX时间戳和微秒数 |
1.UNIX时间戳
UNIX时间戳是一种时间的表示方式,它的存在是为了解决编程环境中时间运算的问题。例如,在处理时间和日期时,推算起来会比较复杂,因其除了时间进位以外,还要涉及不同的月份天数等,所以使用简单的运算是无法解决的。
UNIX时间戳(UNIX timestamp)定义了从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数,以32位二进制数表示。其中,1970年01月01日零点也叫作UNIX纪元,具体示例如下。
<?phpecho time(); //输出结果:1619008603echo '<br>';echo mktime(0,0,0,4,21,2021); //输出结果:1618934400echo '<br>';echo strtotime('2021-4-21'); //输出结果:1618934400echo '<br>';echo microtime(); //输出结果:0.70563600 1619008603echo '<br>';echo microtime(true); //输出结果:1619008603.7056?>
在上述示例中,time()函数用于获取当前时间的UNIX时间戳,mktime()和strtotime()函数可将给定的日期时间转换成UNIX时间戳,前者的参数分别表示“时分秒月日年”,后者可以是任意时间的字符串。函数microtime()用于获取当前UNIX时间戳和微秒数,不设置参数时,返回值前面一段数字表示微妙数,后面一段数字表示秒数;设置参数时,小数点前表示秒数,小数点后表示微秒数。
2.格式化时间戳
对于用户来说,时间戳的直接输出,会让其看到一个毫无意义的整型数值。为了将时间戳表示的时间以友好的形式显示出来,可以对时间戳进行格式化,具体示例如下。
<?phpecho date('Y-m-d H:i:s'); //输出结果:2021-04-21 20:39:58echo '<br>';echo date('Y-m-d',1618934400); //输出结果:2021-04-21?>
在上述date()函数的示例中,第1个参数表示格式化日期时间的样式,第2个参数表示待格式化的时间戳,省略时表示格式化当前时间戳。关于date()函数格式化日期的常用字符表示含义如表所示:

