func_get_args

(PHP 4, PHP 5, PHP 7, PHP 8)

func_get_args返回包含函数参数列表的数组

描述

func_get_args(): array

获取函数参数列表的数组。

此函数可与 func_get_arg()func_num_args() 结合使用,以允许用户定义的函数接受可变长度参数列表。

参数

此函数没有参数。

返回值

返回一个数组,其中每个元素都是当前用户定义函数参数列表中相应成员的副本。

错误/异常

如果从用户定义函数之外调用,则会生成警告。

示例

示例 #1 func_get_args() 示例

<?php
function foo()
{
$numargs = func_num_args();
echo
"参数数量: $numargs \n";
if (
$numargs >= 2) {
echo
"第二个参数是: " . func_get_arg(1) . "\n";
}
$arg_list = func_get_args();
for (
$i = 0; $i < $numargs; $i++) {
echo
"参数 $i 是: " . $arg_list[$i] . "\n";
}
}

foo(1, 2, 3);
?>

上面的示例将输出

Number of arguments: 3 
Second argument is: 2
Argument 0 is: 1
Argument 1 is: 2
Argument 2 is: 3

示例 #2 func_get_args() 按引用和按值传递参数的示例

<?php
function byVal($arg) {
echo
'传递时: ', var_export(func_get_args()), PHP_EOL;
$arg = 'baz';
echo
'更改后: ', var_export(func_get_args()), PHP_EOL;
}

function
byRef(&$arg) {
echo
'传递时: ', var_export(func_get_args()), PHP_EOL;
$arg = 'baz';
echo
'更改后: ', var_export(func_get_args()), PHP_EOL;
}

$arg = 'bar';
byVal($arg);
byRef($arg);
?>

上面的示例将输出


传递时: array (
0 => 'bar',
)
更改后: array (
0 => 'baz',
)
传递时: array (
0 => 'bar',
)
更改后: array (
0 => 'baz',
)

注意

注意:

从 PHP 8.0.0 开始,func_*() 函数族旨在对命名参数基本透明,将参数视为全部按位置传递,缺少的参数用其默认值代替。此函数会忽略未知命名可变参数的收集。未知命名参数的收集只能通过可变参数访问。

注意:

如果参数按引用传递,则对参数的任何更改都将反映在此函数返回的值中。从 PHP 7 开始,如果参数按值传递,也会返回当前值。

注意: 此函数仅返回传递参数的副本,不会考虑默认(未传递)参数。

参见

添加注释

用户贡献的注释 12 个注释

65
T.M.
19 年前
使用动态参数计算平均值的简单函数
<?php
function average(){
return
array_sum(func_get_args())/func_num_args();
}
print
average(10, 15, 20, 25); // 17.5
?>
11
cobrattila at gmail dot com
4 年前
如果您想按引用获取参数,而不是 func_get_args(),您可以简单地使用

<?php
function args_byref(&...$args) {
// 在此处修改 $args 数组
}
?>

应归功于 Markus Malkusch 在 Stackoverflow 上指出这一点。
https://stackoverflow.com/a/29181826/1426064
16
anderson at francotecnologia dot com
15 年前
如何创建一个多态/"重载"函数

<?php
函数 select()
{
$t = '';
$args = func_get_args();
遍历 (
$args 作为 &$a) {
$t .= gettype($a) . '|';
$a = mysql_real_escape_string($a);
}
如果 (
$t != '') {
$t = substr($t, 0, - 1);
}
$sql = '';
switch (
$t) {
case
'integer':
// 通过 ID 搜索
$sql = "id = {$args[0]}";
break;
case
'string':
// 通过名称搜索
$sql = "name LIKE '%{$args[0]}%'";
break;
case
'string|integer':
// 通过名称和状态搜索
$sql = "name LIKE '%{$args[0]}%' AND status = {$args[1]}";
break;
case
'string|integer|integer':
// 通过名称搜索,并设置限制
$sql = "name LIKE '%{$args[0]}%' LIMIT {$args[1]},{$args[2]}";
break;
默认:
// :P
$sql = '1 = 2';
}
返回
mysql_query('SELECT * FROM table WHERE ' . $sql);
}
$res = select(29); // 通过 ID
$res = select('Anderson'); // 通过名称
$res = select('Anderson', 1); // 通过名称和状态
$res = select('Anderson', 0, 5); // 通过名称搜索,并设置限制
?>
2
daveNO at ovumSPAMdesign dot com
22 年前
<?php
// 如何在 PHP 中模拟命名参数。
// 由 Dave Benjamin <[email protected]> 提供

// 将 func_get_args() 返回的数组转换为一个名称/值
// 对,可以由 extract() 处理。
函数 varargs($args) {
$count = count($args);
对于 (
$i = 0; $i < $count; $i += 2) {
$result[$args[$i]] = $args[$i + 1];
}

返回
$result;
}

// 示例
函数 test($ref1, &$ref2) {
// 默认参数在此处。
$foo = "oof";

// 做一些魔法。
extract(varargs(func_get_args()));

回显
nl2br("\n\$var1 = $var1");
回显
nl2br("\n\$var2 = $var2");
回显
nl2br("\n\$foo = $foo\n\n");

// 修改一些通过引用传递的变量。
// 请注意,func_get_args() 不会传递引用,因此它们
// 需要在函数定义中显式声明。
$ref1 = 42;
$ref2 = 84;
}

$a = 5;
$b = 6;

回显
nl2br("在调用 test() 之前:\$a = $a\n");
回显
nl2br("在调用 test() 之前:\$b = $b\n");

// 尝试从以下行中删除 'foo, "bar"'。
test($a, $b, var1, "abc", var2, "def", foo, "bar");

回显
nl2br("在调用 test() 之后:\$a = $a\n");
回显
nl2br("在调用 test() 之后:\$b = $b\n");
?>
3
foxkeys at gmail dot com
8 年前
将 func_get_args() 与函数默认值合并
<?php
utils {
/**
* @param 混合[] $args
* @param ReflectionMethod $reflectionMethod
*
* @return 数组
*/
public static 函数 mergeArgsWithDefaults( $args, \ReflectionMethod $reflectionMethod ) {
遍历 (
array_slice( $reflectionMethod->getParameters(), count( $args ) ) 作为 $param ) {
/**
* @var ReflectionParameter $param
*/
$args[] = $param->getDefaultValue();
}
返回
$args;
}
}

sampleParent {
常量
USER_FILE_TYPE_FILE = 'FILE';
public 函数
select( $idUserFile = null, $idUserFileType = self::USER_FILE_TYPE_FILE ) {
回显
'[$idUserFile=>' . $idUserFile . ', $idUserFileType=>' . $idUserFileType, ']<br/>' . PHP_EOL;
}
}

sample 扩展 sampleParent {
常量
USER_FILE_TYPE_IMG = 'IMG';
public 函数
select( $idUserFile = null, $idUserFileType = self::USER_FILE_TYPE_IMG ) {
返回
call_user_func_array( 'parent::select', \utils::mergeArgsWithDefaults( func_get_args(), 新 ReflectionMethod( __CLASS__, __FUNCTION__ ) ) );
}
}

$sample1 = 新 sampleParent();
$sample1->select();// 输出 "" / self::USER_FILE_TYPE_FILE
$sample1->select(1);// 输出 1 / self::USER_FILE_TYPE_FILE
$sample1->select(2, 'test 1');// 输出 2 / "test 1"
回显 '<br/>' . PHP_EOL;
$sample2 = 新 sample();
$sample2->select();// 输出 "" / self::USER_FILE_TYPE_IMG
$sample2->select(3);// 输出 3 / self::USER_FILE_TYPE_IMG
$sample2->select(4, 'test 2');// 输出 4 / "test 2"
?>
4
OpenTechnologist
12 年前
请注意,可选参数不会被 func_get_args() 以及 func_get_arg() 看到/传递。

例如

<?php
function testfunc($optional = 'this argument is optional..') {
$args = func_get_args();
var_dump($args);
echo
$optional;
}
?>

测试用例 #1
testfunc('argument no longer optional..');

结果 #1
array(1) {
[0]=> string(20) "argument no longer optional.."
}
argument no longer optional..

测试用例 #2
testfunc('argument no longer optional..','this is an extra argument');

结果 #2
array(2) {
[0]=> string(29) "argument no longer optional.."
[1]=> string(25) "this is an extra argument"
}
argument no longer optional..

测试用例 #3: -- 结果为空数组
testfunc();

结果 #3
array(0) {
}
this argument is optional..
2
hans at loltek dot net
9 个月前
我想要一个关联列表来存储参数,如果其他人也有这个需求,可以参考我的代码。

我希望 PHP 可以原生支持这种功能,因为核心实现会比这种用户级的回溯+反射实现快很多。
<?php

/**
* 将函数参数以关联数组形式获取
* (类似 func_get_args() 但带有键值)
*
* @param bool $populateMissingArgumentsWithDefaults 是否用默认值填充缺失的参数
*
* @return array
*/
function func_get_args_associative(bool $populateMissingArgumentsWithDefaults = false): array
{
$trace = debug_backtrace(0, 2)[1];
$reflection = null;
if (isset(
$trace['class'])) {
$reflection = new \ReflectionMethod($trace['class'], $trace['function']);
} else {
$reflection = new \ReflectionFunction($trace['function']);
}
$ret = [];
foreach (
$reflection->getParameters() as $param) {
if (
array_key_exists($param->getPosition(), $trace['args'])) {
$ret[$param->name] = $trace['args'][$param->getPosition()];
} elseif (
$populateMissingArgumentsWithDefaults) {
// 由于 "在可选参数之后声明的必填参数隐式为必填" 规则:
assert($param->isDefaultValueAvailable(), "我认为所有参数都在 trace[args] 中或有默认值");
$ret[$param->name] = $param->getDefaultValue();
}
}
return
$ret;
}
?>
1
art at geigel dot com
1 年前
例如,使用 `count()` 获取 `func_get_args()` 返回的数组大小,不会考虑函数定义中已分配默认值的参数。

示例

function foo($bar=true) {
echo count(func_get_args());
}

foo();
// 输出 0

foo("bar");
// 输出 1

当函数需要在没有值的情况下返回默认行为(无论是什么)并且 `$bar` 的值可能是 `true`、`false`、`null` 等时,这是一个有用的测试条件。
0
maarten at ba dot be
11 年前
似乎这个函数只返回一个副本,并且丢失了它的引用信息,请使用这个效率低下的脏方法作为替代方案。

在编写本文时,它目前返回所有参数作为引用,而不是只返回以引用方式传递的参数...

<?php
function func_get_args_byref() {
$trace = debug_backtrace();
return
$trace[1]['args'];
}
?>
0
mitko at edabg dot com
15 年前
<?php
/*
此示例演示如何使用未知变量参数作为引用。
func_get_args() 不以引用方式返回参数,但
debug_backtrace() 的 "args" 是以引用方式返回的。
在 PHP 5 中,这样做没有特别意义,因为以引用方式调用参数
已弃用,并会产生警告。
*/

class foo {

var
$bar = "default bar";

function
foo(/*variable arguments*/) {
// func_get_args 返回参数的副本
// $args = func_get_args();
// debug_backtrace 返回参数的引用
$stack = debug_backtrace();
$args = array();
if (isset(
$stack[0]["args"]))
for(
$i=0; $i < count($stack[0]["args"]); $i++)
$args[$i] = & $stack[0]["args"][$i];
call_user_func_array(array(&$this, 'bar'), $args);
}


function
bar($bar = NULL) {
if (isset(
$bar))
$this->bar = & $bar;
}
}

$global_bar = "bar global";
$foo = & new foo();
echo
"foo->bar: ".$foo->bar."</br>\n";
$foo->bar = "new bar";
echo
"global_bar: ".$global_bar."</br>\n";
/*
结果:
foo->bar: default bar</br>
global_bar: bar global</br>
*/

$foo = & new foo(&$global_bar);
echo
"foo->bar: ".$foo->bar."</br>\n";
$foo->bar = "new bar";
echo
"global_bar: ".$global_bar."</br>\n";
/*
结果:
foo->bar: bar global</br>
global_bar: new bar</br>
*/

?>
0
ario [a] mail [dot] utexas [dot] edu
17 年前
"因为此函数依赖于当前作用域来确定参数的详细信息,所以它不能用作函数参数。如果您必须传递此值,请将结果分配给一个变量,然后传递该变量。"

这意味着以下代码会产生错误

<?php

function foo($list)
{
echo
implode(', ', $list);
}

function
foo2()
{
foo(func_get_args());
}

foo2(1, 2, 3);

?>

但是,您可以通过以下方式轻松解决此问题

<?php

function foo($list)
{
echo
implode(', ', $list);
}

function
foo2()
{
foo($args = func_get_args());
}

foo2(1, 2, 3);

?>

这会从 `foo2()` 中捕获上下文,使其合法。您将得到预期的输出。

"1, 2, 3"
0
Anonymous
23 年前
您可以使用数组将可变数量的参数传递给函数,同时保持引用完整。当然,缺点是调用的函数需要知道它的参数在数组中。

<?php
// 输出 "hello mutated world"
function mutator($args=null) {
$n=count($args);
while(
$i<$n) $args[$i++] = "mutated";
}
$a = "hello";
$b = "strange";
$c = "world";
mutator(array($a, &$b, $c));
echo
"$a $b $c";
?>
To Top