通過參數(shù)列表可以傳遞信息到函數(shù),即以逗號作為分隔符的表達式列表。函數(shù)在實際調用之前,值參數(shù)是從左向右求值的(及早求值)。
PHP 支持按值傳遞參數(shù)(默認),通過引用傳遞參數(shù) 以及 默認參數(shù)。也支持 可變長度參數(shù)列表 和 命名參數(shù)。
示例 #1 向函數(shù)傳遞數(shù)組
<?php
function takes_array($input)
{
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>
從 PHP 8.0.0 開始,函數(shù)參數(shù)列表可以包含一個尾部的逗號,這個逗號將被忽略。這在參數(shù)列表較長或包含較長的變量名的情況下特別有用,這樣可以方便地垂直列出參數(shù)。
示例 #2 函數(shù)參數(shù)使用尾部逗號
<?php
function takes_many_args(
$first_arg,
$second_arg,
$a_very_long_argument_name,
$arg_with_default = 5,
$again = 'a default string', // 在 8.0.0 之前,這個尾部的逗號是不允許的。
)
{
// ...
}
?>
從 PHP 8.0.0 開始,廢棄在可選參數(shù)后聲明強制參數(shù)??梢酝ㄟ^刪除默認值來解決。
此規(guī)則一個例外是 Type $param = null
形式的參數(shù),
其中 null
默認值使類型隱性允許為空。
這種做法依然允許,但是推薦使用顯性可為 null 的類型代替。
示例 #3 強制參數(shù)后聲明可選參數(shù)
<?php
function foo($a = [], $b) {} // 之前
function foo($a, $b) {} // 之后
function bar(A $a = null, $b) {} // 同時可用
function bar(?A $a, $b) {} // 官方推薦的寫法
?>
默認情況下,函數(shù)參數(shù)通過值傳遞(因而即使在函數(shù)內部改變參數(shù)的值,它并不會改變函數(shù)外部的值)。如果希望允許函數(shù)修改它的參數(shù)值,必須通過引用傳遞參數(shù)。
如果想要函數(shù)的一個參數(shù)總是通過引用傳遞,可以在函數(shù)定義中該參數(shù)的前面加上符號 &:
示例 #4 用引用傳遞函數(shù)參數(shù)
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // 輸出 'This is a string, and something extra.'
?>
函數(shù)可以定義 C++ 風格的標量參數(shù)默認值,如下所示:
示例 #5 在函數(shù)中使用默認參數(shù)
<?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 還允許使用數(shù)組 array 和特殊類型 null
作為默認參數(shù),例如:
示例 #6 使用非標量類型作為默認參數(shù)
<?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");
?>
默認值必須是常量表達式,不能是諸如變量,類成員,或者函數(shù)調用等。
注意當使用默認參數(shù)時,任何默認參數(shù)必須放在任何非默認參數(shù)的右側;否則,函數(shù)將不會按照預期的情況工作??紤]下面的代碼片斷:
示例 #7 函數(shù)默認參數(shù)的不正確用法
<?php
function makeyogurt($type = "acidophilus", $flavour)
{
return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt("raspberry"); // 不會按照預期工作
?>
以上例程會輸出:
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 .
現(xiàn)在,比較上面的例子和這個例子:
示例 #8 函數(shù)默認參數(shù)正確的用法
<?php
function makeyogurt($flavour, $type = "acidophilus")
{
return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt("raspberry"); // 按預期工作
?>
以上例程會輸出:
Making a bowl of acidophilus raspberry.
注意: 傳引用的參數(shù)也可以有默認值。
PHP 在用戶自定義函數(shù)中支持可變數(shù)量的參數(shù)列表。由
...
語法實現(xiàn)。
注意: 還可以使用以下函數(shù)來獲取可變參數(shù) func_num_args()、 func_get_arg() 和 func_get_args(),不建議使用此方式,請使用
...
來替代。
包含 ...
的參數(shù),會轉換為指定參數(shù)變量的一個數(shù)組,見以下示例:
示例 #9 使用 ...
來訪問變量參數(shù)
<?php
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
以上例程會輸出:
10
也可以使用 ...
語法來傳遞 array 或
Traversable
做為參數(shù)到函數(shù)中:
示例 #10 使用 ...
來傳遞參數(shù)
<?php
function add($a, $b) {
return $a + $b;
}
echo add(...[1, 2])."\n";
$a = [1, 2];
echo add(...$a);
?>
以上例程會輸出:
3 3
你可以在
...
前指定正常的位置參數(shù)。在這種情況下,只有不符合位置參數(shù)的尾部參數(shù)才會被添加到
...
生成的數(shù)組中。
你也可以在
...
標記前添加一個
類型聲明。如果存在這種情況,那么
...
捕獲的所有參數(shù)都必須匹配參數(shù)類型。
示例 #11 輸入提示的變量參數(shù)
<?php
function total_intervals($unit, DateInterval ...$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';
// 這將會失敗,因為 null 不是 DateInterval 對象。
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
最后,你還可以給參數(shù)傳遞
引用變量,通過在
...
前加上一個 (&
) 符號來實現(xiàn)。
不需要特殊的語法來聲明一個函數(shù)是可變的;但是訪問函數(shù)的參數(shù)必須使用 func_num_args(), func_get_arg() 和 func_get_args() 函數(shù)。
上面的第一個例子在早期 PHP 版本中的實現(xiàn)如下:
示例 #12 在 PHP 早期版本中訪問可變參數(shù)
<?php
function sum() {
$acc = 0;
foreach (func_get_args() as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
以上例程會輸出:
10
PHP 8.0.0 開始引入了命名參數(shù)作為現(xiàn)有位置參數(shù)的擴展。命名參數(shù)允許根據(jù)參數(shù)名而不是參數(shù)位置向函數(shù)傳參。這使得參數(shù)的含義自成體系,參數(shù)與順序無關,并允許任意跳過默認值。
命名參數(shù)通過在參數(shù)名前加上冒號來傳遞。允許使用保留關鍵字作為參數(shù)名。參數(shù)名必須是一個標識符,不允許動態(tài)指定。
示例 #13 命名參數(shù)的語法
<?php
myFunction(paramName: $value);
array_foobar(array: $value);
// 不支持。
function_name($variableStoringParamName: $value);
?>
示例 #14 通過位置傳參與命名參數(shù)的對比
<?php
// 使用順序傳遞參數(shù):
array_fill(0, 100, 50);
// 使用命名參數(shù):
array_fill(start_index: 0, count: 100, value: 50);
?>
指定參數(shù)的傳遞順序并不重要。
示例 #15 參數(shù)順序不同的示例(同上例)
<?php
array_fill(value: 50, count: 100, start_index: 0);
?>
命名參數(shù)也可以與位置參數(shù)相結合使用。此種情況下,命名參數(shù)必須在位置參數(shù)之后。也可以只指定一個函數(shù)的部分可選參數(shù),而不考慮它們的順序。
示例 #16 命名參數(shù)與位置參數(shù)結合使用
<?php
htmlspecialchars($string, double_encode: false);
// 等價于
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);
?>
Passing the same parameter multiple times results in an Error exception.
示例 #17 Error exception when passing the same parameter multiple times
<?php
function foo($param) { ... }
foo(param: 1, param: 2);
// 錯誤:命名參數(shù) $param 覆蓋了之前的參數(shù)
foo(1, param: 2);
// 錯誤:命名參數(shù) $param 覆蓋了之前的參數(shù)
?>