4.2 函数的参数
PHP支持按值传递参数(默认),通过引用传递参数及默认参数,也支持可变长度参数列表。PHP支持函数参数类型声明。
4.2.1 参数传递方式
在调用函数时需要向函数传递参数,被传入的参数称作实参,而函数定义的参数为形参。PHP中函数参数传递有两种方式:按值传递和通过引用传递,还可以使用默认参数。
1.按值传递
按值传递的参数相当于在函数内部有这个参数的备份,即使在函数内部改变参数的值,也并不会改变函数外部的值,示例如下:
<? php function test($a){ $a = $a + 1; return $a; } $a = 1; echo test($a); test(2); echo $a; ?>
执行以上代码的结果为:
2 3 1
2.通过引用传递参数
如果希望允许修改函数的参数值,就必须通过引用传递参数,这样我们在函数内部是对这个参数本身进行操作。
示例如下:
<? php function test(&$a){ $a=$a+1; return$a; } $x=1; echo test($x); echo$x; ?>
当调用一次test()函数后,$x的值被改变,执行以上代码的结果为:
2 2
注意,以下这种情况PHP会报错:
<? php function test(&$a){ $a = $a + 1; return $a; } test(2); //引用传递的参数必须是一个变量 ?>
执行以上代码会报错“Fatal error: Only variables can be passed by reference”。
3.默认参数
PHP支持函数默认参数,允许使用数组array和特殊类型NULL作为默认参数,默认值必须是常量表达式,不能是变量、类成员或函数调用等。
例如:
<? php function test($arr=array('lily', 'andy', 'ricky'), $str='apple'){ echo "I am$arr[1], I love$str<br/>"; } $names=['sily', 'celon', 'tom']; $fruit='orange'; test(); test($names, $fruit); ?>
执行以上代码的结果为:
I am andy, I love apple I am celon, I love orange
为了避免出现意外情况,一般将默认参数放在非默认参数的右侧。
<? php function makeyogurt($type="acidophilus",$flavour){ return "Making a bowl of$type$flavour.\n"; } echo makeyogurt("raspberry"); ?>
报错信息:
Warning: Missing argument 2 for makeyogurt(), called in /Library/WebServer/Documents/book/str.php on line 284 and defined in /Library/WebServer/Documents/book/str.php on line 279 Making a bowl of raspberry .
若将$type = "acidophilus"放在参数的最右侧,则不会报错。
4.2.2 参数类型声明
在PHP 5中已引入函数的参数类型声明,如果给定的值不是一个合法的参数类型,那么在PHP 5中会出现一个fatal error,在PHP 7中则会抛出一个TypeErrot exception。在PHP 7中增加了参数可声明的类型种类,函数可声明的参数类型如表4-1所示。
表4-1 参数声明类型
关于指定参数类型为class类型(关于类的知识请查阅本书第9章)的实例如下:
<? php class C{} class D extends C{} //类D继承自类C class E{} function f(C$c){ echo get_class($c)."\n"; } f(new C); f(new D); f(new E); ?>
执行以上程序的结果是:
C D Fatal error: Uncaught TypeError: Argument 1 passed to f() must be an instance of C, instance of E given, called in /Library/WebServer/Documents/book/str.php on line 293 and defined in /Library/WebServer/Documents/book/str.php:287 Stack trace:#0 /Library/WebServer/Documents/book/str.php(293): f(Object(E)) #1 {main} thrown in /Library/WebServer/Documents/book/str.php on line 287
默认情况下,当传递的参数不是函数指定的参数类型时,PHP会尝试将所传参数转换成指定参数类型。例如,一个函数希望得到一个字符串类型的参数,但假如给其提供的是一个整型参数,PHP就会自动将其转换成字符串类型,或者一个函数希望得到一个整型参数,但却给它传递了一个浮点型的参数,同样也会自动转换。示例如下:
<? php function test(int $a, string $b, string $c){ echo ($a + $b); echo " the string is$c"; } test(3.8,2, 'hello'); ?>
执行以上代码的打印结果为:
5 the string is hello
注意,在讲浮点型转成整型时只取其中的整数部分。
在PHP 7中,可以使用declare(strict_types=1) 设置严格模式,这样只有在传递的参数与函数期望得到的参数类型一致时才能正确执行,否则会抛出错误。只有一种情况例外,就是当函数期望得到的是一个浮点型数据而提供的是整型时,函数也能正常被调用。请看如下示例:
<? php declare(strict_types=1); function test(int$a, int$b, string$c){ echo ($a+$b); echo " the string is$c"; } test(3.8,2, 'hello'); ? >
此处declare声明了PHP为严格模式,而传入的参数与函数期望得到的参数类型不一致,所以会报错,例如:
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be of the type integer, float given, called in /Library/WebServer/Documents/book/str.php on line 285 and defined in /Library/WebServer/Documents/book/str.php:281 Stack trace:#0/Library/WebServer/Documents/book/str.php(285): test(3.8, 2,'hello')#1{main}thrown in/Library/WebServer/Documents/book/str.php on line 281
4.2.3 可变参数数量
在PHP 5.6及以后的版本中,参数可包含“…”来表示函数可接受一个可变数量的参数,可变参数将会被当作一个数组传递给函数。看如下示例:
<? php function test(...$num){ $acc=0; foreach ($num as$key=>$value){ $acc+=$value; } return$acc; } echo test(1,2,3,4); ?>
给test()函数传递的参数1 2 3 4在函数内部将会被当作数组处理,运行以上代码的结果为:10。