首页 > PHP 阅读:20

PHP函数参数的传递

PHP 支持两种参数传递方式,分别是按值传递(默认)和按引用传递。另外,PHP 还支持默认参数和可变长度参数列表。

参数传递方式

在调用函数时需要向函数传递参数,被传入的参数称作实参,而函数定义的参数为形参。PHP 中函数参数传递有 2 种方式:按值传递和通过引用传递。

按值传递

按值传递的参数相当于在函数内部有这个参数的备份,即使在函数内部改变参数的值,也并不会改变函数外部的值,示例如下:
<?php
function test($a){
    $a = $a + 1;
     return $a;
}
$a = 1;
echo test($a);
test(2);
echo $a;
?>
执行以上代码的结果为:

2 3 1

通过引用传递参数

如果希望允许函数修改它的参数值,就必须通过引用传递参数。这样我们在函数内部是对这个参数本身进行操作。示例如下:
<?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”。

默认参数

PHP 支持函数默认参数,允许使用数字、字符串、数组、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"放在参数的最右侧,则不会报错。

参数类型声明

在 PHP 5 中已引入函数的参数类型声明,如果给定的值不是一个合法的参数类型,那么在 PHP 5 中会出现一个 Fatal error,在 PHP 7 中则会抛出一个 TypeError exception。在 PHP 7 中增加了参数可声明的类型种类。PHP 中函数可声明的参数类型如表所示。

参数声明类型
类型 说明 PHP 版本
class/interface name(类,接口) 参数必须是指定类或接口的实例 PHP 5.0.0
Array 参数为数组类型 PHP 5.1.0
Callable 参数为有效的回调类型 PHP 5.4.0
Bool 参数为布尔型 PHP 7.0.0
Float 参数为浮点型 PHP 7.0.0
Int 参数为整型 PHP 7.0.0
String 参数为字符串 PHP 7.0.0
class/interface name(类,接口) 参数必须是指定类或接口的实例 PHP 5.0.0
Array 参数为数组类型 PHP 5.1.0

指定参数类型为 class 类型的实例如下:
<?php
class C{}
class D extends C{}      //类D继承自类C
class E{}
functionf(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

可变参数

在 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() 函数传递的参数 1234 在函数内部将会被当作数组处理,运行以上代码的结果为:

10