func_get_args

Returns all arguments passed to the current function as a numerically indexed array.

Signature
func_get_args(): array
  • Added in PHP 4.0

Return value

arrayA zero-indexed array containing a copy of each argument in the current user-defined function's argument list.

Errors

Throws an Error if called from the global scope or invoked dynamically (for example through call_user_func).

Changelog

  • PHP 8.0Named arguments are treated as if passed positionally; parameters that were not supplied are replaced with their declared defaults, and unknown named variadic arguments are ignored.
  • PHP 7.0Current values are returned for by-value arguments, so reassigning a parameter before the call changes what is returned.

func_get_args() hands you every argument the current function received, including ones with no matching parameter. Before PHP 5.6 it was the only way to write a variadic function; today the ...$args syntax is almost always the better choice because it is visible in the signature, can be typed, and works with reflection and IDEs.

Where it is still the right tool

Two situations. First, maintaining an existing API whose signature you cannot change but whose extra arguments you need to read. Second, a wrapper that must forward whatever it was given without declaring anything, typically combined with call_user_func_array() or the spread operator.

Named arguments

Since PHP 8, calls made with named arguments are normalised into positional order and any parameter you skipped is filled in with its default. That is usually what you want, but it means the array you get back does not tell you which arguments were explicitly supplied. Use func_num_args() if the difference matters.

Combining with declared parameters

The array always starts at index 0 with the first argument, including ones bound to named parameters. If your function declares $glue and then reads the rest, you must drop the leading elements yourself.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Accepting an unlimited argument list in a legacy function whose signature must not change
  • Forwarding every received argument to another callable inside a proxy or decorator
  • Logging exactly what a function was called with inside a debug wrapper
  • Building a __call() magic method that replays arguments onto a real method

Frequently asked questions

What is the difference between func_get_args and the ...$args syntax?

They give you the same values, but ...$args is declared in the signature, can be type-hinted, and is visible to reflection, IDEs and static analysers. Use the variadic syntax in new code and keep func_get_args() for legacy signatures you cannot change.

Does func_get_args include declared parameters?

Yes. The array starts at index 0 with the first argument, whether or not it was bound to a named parameter, so use array_slice() or array_shift() to skip the ones you declared.

Why does func_get_args return values I did not pass?

Since PHP 8.0, calls that use named arguments are normalised into positional order and any skipped parameter is filled in with its default. Call func_num_args() if you need to know how many arguments were literally supplied.

More examples

Named arguments are normalised to positions

The first call prints Array ( [0] => A [1] => B [2] => see ) — the skipped parameters were filled in with their defaults. The second prints only two elements, because arguments after the last one supplied are not padded.

Example · php
<?php
function report(string $a = 'A', string $b = 'B', string $c = 'C'): void
{
    print_r(func_get_args());
}

report(c: 'see');
report('one', 'two');

Forwarding an unknown argument list

Each call prints the traced signature and then the result: max(4, 11, 7) followed by 11, then str_pad(x, 5, .) followed by x.... array_slice() drops the $fn argument that the function declared for itself.

Example · php
<?php
function traced(string $fn): mixed
{
    $args = array_slice(func_get_args(), 1);
    echo "$fn(", implode(', ', array_map('strval', $args)), ")\n";
    return $fn(...$args);
}

echo traced('max', 4, 11, 7), "\n";
echo traced('str_pad', 'x', 5, '.'), "\n";

It cannot be called indirectly

Prints an Error saying func_get_args() cannot be called dynamically. The function needs the calling frame to read arguments from, and a dynamic call would give it the wrong one, so the engine refuses outright.

Example · php
<?php
function attempt(): string
{
    try {
        $args = call_user_func('func_get_args');
        return 'got ' . count($args);
    } catch (Error $e) {
        return get_class($e) . ': ' . $e->getMessage();
    }
}

echo attempt('a', 'b'), "\n";

Discussion

  • Be the first to comment on this lesson.