PHP 函数参数说明

通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。参数是从左向右求值的。

PHP 支持按值传递参数(默认),通过引用传递参数以及默认参数。也支持可变长度参数列表

一、按值传递参数

直接按值传递参数示例

<?php

function sum($a, $b) {
    return $a + $b;
}
echo sum(1,2);//3

二、通过引用传递参数

默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数

如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &

用引用传递函数参数示例

<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str;// outputs 'This is a string, and something extra.'
?> 

三、默认参数的值

函数可以定义 C++ 风格的标量参数默认值,如下所示:

<?php
function makeCoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");

//输出结果为
//Making a cup of cappuccino.
//Making a cup of .
//Making a cup of espresso.

?> 

PHP 还允许使用数组 **array**和特殊类型 NULL 作为默认参数,例如:

使用非标量类型作为默认参数

<?php
function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
{
    $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
    return "Making a cup of ".join(", ", $types)." with $device.\n";
}
echo makecoffee();
echo makecoffee(array("cappuccino", "lavazza"), "teapot");
?>

默认值必须是常量表达式,不能是诸如变量,类成员,或者函数调用等。

注意当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧;否则,函数将不会按照预期的情况工作

自 PHP 5 起,传引用的参数也可以有默认值。

下面是错误用法

<?php
function makeyogurt($type = "acidophilus", $flavour)
{
    return "Making a bowl of $type $flavour.\n";
}

echo makeyogurt("raspberry");   // won't work as expected

//以上例程会输出:

/**
Warning: Missing argument 2 in call to makeyogurt() in 
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
Making a bowl of raspberry .
**/
?> 

四、可变数量的参数列表

PHP 在用户自定义函数中支持可变数量的参数列表。在 PHP 5.6 及以上的版本中,由...语法实现;在 PHP 5.5 及更早版本中,使用函数func_num_args()func_get_arg(),和func_get_args()

在PHP 5.6和更高版本中,参数列表可能包括表示函数接受可变数量参数的标记。参数将以数组的形式传递给给定变量;

使用...接受可变参数

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);//10
echo sum(1, 2, 3, 4,5);//15
?> 

你也可以用当调用函数将数组或可遍历变量或字符解析到参数列表时

<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])."\n";//输出3

$a = [1, 2];
echo add(...$a);//输出3
?> 

在PHP 5.5及更早版本中访问变量参数

<?php
function sum() {
    $acc = 0;
    foreach (func_get_args() as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);//10
?> 

五、参数类型声明

Note:

在PHP 5中,类型声明也被称为类型提示。

类型声明允许函数在调用时要求参数为特定类型。 如果给出的值类型不对,那么将会产生一个错误: 在PHP 5中,这将是一个可恢复的致命错误,而在PHP 7中将会抛出一个TypeError异常。

为了指定一个类型声明,类型应该加到参数名前。这个声明可以通过将参数的默认值设为**NULL来实现允许传递NULL**。

Warning

不支持上述标量类型的别名。相反,它们被视为类名或接口名。例如,使用boolean作为形参或返回类型将要求实参或返回值是类或接口boolean的实例,而不是bool类型:

<?php
 function test(boolean $param) {}
 test(true);
//以上例程会输出:
/**
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1
**/
 ?> 

5.1 基本类的类型声明

<?php
class C {}
class D extends C {}

// This doesn't extend 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 - on line 14 and defined in -:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
  thrown in - on line 8

5.2 基本接口的类型声明

<?php
interface I { public function f(); }
class C implements I { public function f() {} }

// This doesn't implement I.
class E {}

function f(I $i) {
    echo get_class($i)."\n";
}

f(new C);
f(new E);
/**
输出结果:
C
Fatal error: Uncaught TypeError: Argument 1 passed to f() must implement interface I, instance of E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
  thrown in - on line 8
**/
?>  

5.3 空类型声明

<?php
class C {}

function f(C $c = null) {
    var_dump($c);
}

f(new C);
f(null);

/**
输出结果:
object(C)#1 (0) {
}
NULL
**/
?>  

六、严格类型

默认情况下,如果能做到的话,PHP将会强迫错误类型的值转为函数期望的标量类型。例如,一个函数的一个参数期望是string,但传入的是integer,最终函数得到的将会是一个string类型的值。

可以基于每一个文件开启严格模式。在严格模式中,只有一个与类型声明完全相符的变量才会被接受,否则将会抛出一个TypeError。 唯一的一个例外是可以将integer传给一个期望float的函数。

使用 declare 语句和strict_types 声明来启用严格模式

谨慎操作

启用严格模式同时也会影响返回值类型声明

Note:

严格类型适用于在启用严格模式的文件内的函数调用,而不是在那个文件内声明的函数。 一个没有启用严格模式的文件内调用了一个在启用严格模式的文件中定义的函数,那么将会遵循调用者的偏好(弱类型),而这个值将会被转换。

Note:

严格类型仅用于标量类型声明,也正是因为如此,这需要PHP 7.0.0 或更新版本,因为标量类型声明也是在那个版本中添加的。

6.1 严格类型示例

<?php
declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));
var_dump(sum(1.5, 2.5));

/**
输出结果:
int(3)

Fatal error: Uncaught TypeError: Argument 1 passed to sum() must be of the type integer, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
  thrown in - on line 4
**/
?> 

6.2 弱类型示例

<?php
function sum(int $a, int $b) {
    return $a + $b;
}

var_dump(sum(1, 2));

// These will be coerced to integers: note the output below!
var_dump(sum(1.5, 2.5));

/**
结果输出:
int(3)
int(3)
**/
?> 

6.3 捕获TypeError示例

<?php
declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

try {
    var_dump(sum(1, 2));
    var_dump(sum(1.5, 2.5));
} catch (TypeError $e) {
    echo 'Error: '.$e->getMessage();
}

/**
结果输出:

int(3)
Error: Argument 1 passed to sum() must be of the type integer, float given, called in - on line 10
**/
?>  

joshua317博客
请先登录后发表评论
  • latest comments
  • 总共0条评论