views:

82

answers:

1

In Ruby

def my_func(foo,bar,*zim)
  [foo, bar, zim].collect(&:inspect)
end

puts my_func(1,2,3,4,5)

# 1
# 2
# [3, 4, 5]

In PHP (5.3)

function my_func($foo, $bar, ... ){
  #...
}

What's the best way to to do this in PHP?

+2  A: 

Try

  • func_get_args — Returns an array comprising a function's argument list

PHP Version of your Ruby Snippet

function my_func($foo, $bar)
{
    $arguments = func_get_args();
    return array(
        array_shift($arguments),
        array_shift($arguments),
        $arguments
    );
}
print_r( my_func(1,2,3,4,5,6) );

or just

function my_func($foo, $bar)
{
    return array($foo , $bar , array_slice(func_get_args(), 2));
}

gives

Array
(
    [0] => 1
    [1] => 2
    [2] => Array
        (
            [0] => 3
            [1] => 4
            [2] => 5
            [3] => 6
        )
)

Note that func_get_args() will return all arguments passed to a function, not just those not in the signature. Also note that any arguments you define in the signature are considered required and PHP will raise a Warning if they are not present.

If you only want to get the remaining arguments and determine that at runtime, you could use the ReflectionFunction API to read the number of arguments in the signature and array_slice the full list of arguments to contain only the additional ones, e.g.

function my_func($foo, $bar)
{
    $rf = new ReflectionFunction(__FUNCTION__);
    $splat = array_slice(func_get_args(), $rf->getNumberOfParameters());
    return array($foo, $bar, $splat);
}

Why anyone would want that over just using func_get_args() is beyond me, but it would work. More straightforward is accessing the arguments in any of these ways:

echo $foo;
echo func_get_arg(0); // same as $foo
$arguments = func_get_args();
echo $arguments[0]; // same as $foo too

If you need to document variable function arguments, PHPDoc suggest to use

/**
 * @param Mixed $foo Required
 * @param Mixed $bar Required
 * @param Mixed, ... Optional Unlimited variable number of arguments
 * @return Array
 */

Hope that helps.

Gordon
Gordon, the splat collects all the overloaded params into an array. I was afraid PHP was going to have to hurl on itself to get this type of functionality...
macek
You don't even need $foo and $bar in the function definition, other than for "documentation" purposes - function my_func() would suffice - though if $foo and $bar are in the function definition they can be referenced as such in the function code.
Mark Baker
@macek well, PHP does not have a facility to only collect the overloaded params, but `func_get_args` will contain any arguments passed to a function independent from it's signature. In the above function `$foo` and `$bar` makes these two required arguments. PHP will raise an error if you do not supply them. Inside the function it's `$foo is func_get_arg(0) is func_get_args()[0]`
Gordon
@macek just split the resulting array into the variables you want using something like list($foo, $baz, $baz) = array(). http://us3.php.net/list Also, you're bound to get more useful answers when you don't hurl on someone's chosen platform.
Alan Storm
@Alan, I wasn't intending to hurl on PHP; I use it all the time. PHP just isn't very suitable for meta programming.
macek