函数的参数

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

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

Example #1 向函数传递数组

<?php
function takes_array($input)
{
    echo 
"$input[0] + $input[1] = "$input[0]+$input[1];
}
?>

通过引用传递参数

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

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

Example #2 用引用传递函数参数

<?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++ 风格的标量参数默认值,如下所示:

Example #3 在函数中使用默认参数

<?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 作为默认参数,例如:

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

<?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");
?>

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

注意当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧;否则,函数将不会按照预期的情况工作。考虑下面的代码片断:

Example #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 .

现在,比较上面的例子和这个例子:

Example #6 函数默认参数正确的用法

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

echo 
makeyogurt("raspberry");   // works as expected
?>

以上例程会输出:

Making a bowl of acidophilus raspberry.

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

Type declarations

Note:

Type declarations were also known as type hints in PHP 5.

Type declarations allow functions to require that parameters are of a certain type at call time. If the given value is of the incorrect type, then an error is generated: in PHP 5, this will be a recoverable fatal error, while PHP 7 will throw a TypeError exception.

To specify a type declaration, the type name should be added before the parameter name. The declaration can be made to accept NULL values if the default value of the parameter is set to NULL.

Valid types

Type Description Minimum PHP version
Class/interface name The parameter must be an instanceof the given class or interface name. PHP 5.0.0
array The parameter must be an array. PHP 5.1.0
callable The parameter must be a valid callable. PHP 5.4.0
bool The parameter must be a boolean value. PHP 7.0.0
float The parameter must be a floating point number. PHP 7.0.0
int The parameter must be an integer. PHP 7.0.0
string The parameter must be a string. PHP 7.0.0

范例

Example #7 Basic class type declaration

<?php
class {}
class 
extends {}

// This doesn't extend C.
class {}

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

Example #8 Basic interface type declaration

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

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

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

Example #9 Nullable type declaration

<?php
class {}

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

f(new C);
f(null);
?>

以上例程会输出:

object(C)#1 (0) {
}
NULL

Strict typing

By default, PHP will coerce values of the wrong type into the expected scalar type if possible. For example, a function that is given an integer for a parameter that expects a string will get a variable of type string.

It is possible to enable strict mode on a per-file basis. In strict mode, only a variable of exact type of the type declaration will be accepted, or a TypeError will be thrown. The only exception to this rule is that an integer may be given to a function expecting a float.

To enable strict mode, the declare statement is used with the strict_types declaration:

Caution

Enabling strict mode will also affect return type declarations.

Note:

Strict typing applies to function calls made from within the file with strict typing enabled, not to the functions declared within that file. If a file without strict typing enabled makes a call to a function that was defined in a file with strict typing, the caller's preference (weak typing) will be respected, and the value will be coerced.

Note:

Strict typing is only defined for scalar type declarations, and as such, requires PHP 7.0.0 or later, as scalar type declarations were added in that version.

Example #10 Strict typing

<?php
declare(strict_types=1);

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

var_dump(sum(12));
var_dump(sum(1.52.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

Example #11 Weak typing

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

var_dump(sum(12));

// These will be coerced to integers: note the output below!
var_dump(sum(1.52.5));
?>

以上例程会输出:

int(3)
int(3)

Example #12 Catching TypeError

<?php
declare(strict_types=1);

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

try {
    
var_dump(sum(12));
    
var_dump(sum(1.52.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

可变数量的参数列表

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

... in PHP 5.6+

In PHP 5.6 and later, argument lists may include the ... token to denote that the function accepts a variable number of arguments. The arguments will be passed into the given variable as an array; for example:

Example #13 Using ... to access variable arguments

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

echo 
sum(1234);
?>

以上例程会输出:

10

You can also use ... when calling functions to unpack an array or Traversable variable or literal into the argument list:

Example #14 Using ... to provide arguments

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

echo 
add(...[12])."\n";

$a = [12];
echo 
add(...$a);
?>

以上例程会输出:

3
3

You may specify normal positional arguments before the ... token. In this case, only the trailing arguments that don't match a positional argument will be added to the array generated by ....

It is also possible to add a type hint before the ... token. If this is present, then all arguments captured by ... must be objects of the hinted class.

Example #15 Type hinted variable arguments

<?php
function total_intervals($unitDateInterval ...$intervals) {
    
$time 0;
    foreach (
$intervals as $interval) {
        
$time += $interval->$unit;
    }
    return 
$time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo 
total_intervals('d'$a$b).' days';

// This will fail, since null isn't a DateInterval object.
echo total_intervals('d'null);
?>

以上例程会输出:

3 days
Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2

Finally, you may also pass variable arguments by reference by prefixing the ... with an ampersand (&).

Older versions of PHP

No special syntax is required to note that a function is variadic; however access to the function's arguments must use func_num_args(), func_get_arg() and func_get_args().

The first example above would be implemented as follows in PHP 5.5 and earlier:

Example #16 Accessing variable arguments in PHP 5.5 and earlier

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

echo 
sum(1234);
?>

以上例程会输出:

10