tags:

views:

64

answers:

4

In short, what I want is a kind of export() function (but not export()), it creates new variables in symbol table and returns the number of created vars.

I'm trying to figure out if it is possible to declare a function

function foo($bar, $baz)
{
    var_dump(func_get_args());
}

And after that pass an array so that each value of array would represent param.

Just wondering if it is possible (seems that is not).

I need this for dynamic loading, so number of arguments, size of array may vary - please dont offer to pass it as

foo($arr['bar']);

and so on.

Again, ideal thing solution will look like

foo(array('foo'=>'1', 'bar'=>'2', ..., 'zzz'=>64));

for declaration

function foo($foo, $bar, ..., $zzz) {}

As far as I rememeber in some dynamical languages lists may behave like that (or maybe I'm wrong).

(I want to create dynamically parametrized methods in class and built-in mechanism of controlling functions arguments number, default value and so on is quite good for this, so I could get rid of array params and func_get_args and func_get_num calls in the method body).

Thanks in advance.

+4  A: 

You're looking for call_user_func_array

example:

function foo($bar, $baz)
{
    return call_user_func_array('beepboop',func_get_args());
}

function beepboop($bar, $baz){
    print($bar.' '.$baz);
}

foo('this','works');
//outputs: this works
Mike Sherov
Your way is better. +1
GWW
However, I think @dig is wishing to pass in an arbitrary number of args based on an associative array - the order of which (or specific args) could vary I assume? Although this method does allow you to pass an array for conventional args, it is solely dependent on the order of that array and the fact that no keys are missing, the variable names (or array keys) are lost. I think this method would be OK for mutliple args of the same type.
w3d
cont... which is really what `func_get_args()` is for anyway.
w3d
Just want to addSince `call_user_method_array($obj, $method, $params)` is deprecated,one should use `call_user_function_array(array($object, $method), $params)` for object calls.
dig
A: 

How about using extract()?

<?php

/* Suppose that $var_array is an array returned from
   wddx_deserialize */

$size = "large";
$var_array = array("color" => "blue",
                   "size"  => "medium",
                   "shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");

echo "$color, $size, $shape, $wddx_size\n";

?>

(Code taken from PHP example)

GWW
+2  A: 

I don't know about the speed but you could use ReflectionFunction::getParameters() to get what name you gave the parameters, combined with call_user_func_array() to call the function. ReflectionFunction::invokeArgs() could be used as well for invoking.

antennen
But I don't think the parameter names are known at _compile_ time - wouldn't they need to be by this method?
w3d
+1  A: 

What about just passing in an associative array and acting on that array?

George Marian
There is a big movement lately towards this style of coding, especially when working with third party libraries (i.e. the Facebook SDK). I personally would rather use classic function parameters to plainly illustrate the required interface to callers of a function.
Mike Sherov
+1 This is what I would do. Or, cast it to an object and iterate over that, and suggest the type in the function declaration eg. `function MyFunc(MyClass $classInstance) {}`
w3d
@mike I prefer the classic approach as well. However, there is a case to be made for using an associate array. Personally, I prefer a blended approach. The most important/required arguments as function parameters and the optional/extra ones as an associative array, depending on the number of optional/extra arguments.
George Marian
@w3d Good point about about using an object. That is a semantically cleaner approach and a bit easier to document (using PHPDoc for example).
George Marian
@George, true. Lots of good arguments can be said for both sides. Type hinting with a "simple data object is a good compromise, but seems to me almost like overkill. I prefer your idea of a blended approach. Use assoc. arrays for the sugar, parameters for the meat.
Mike Sherov
Just to add/correct my comment above - if you do simply cast an array to an object you get an instance of the stdClass. You can't simply typecast to an arbitrary class (eg. MyClass) in PHP, as might be perceived by my example.
w3d
@mike I agree that the object approach is overkill, in most situations, for the same basic reason I prefer a blended approach. I don't want to be forced to create an array/object every time, for the most typical usage of a function; depending on the complexity. Ultimately, it depends on how strict you need/want to be in your enforcement of function parameters and how many parameters you find necessary for said function.
George Marian
@George, I think we're in agreement here. Thanks for the insight!
Mike Sherov
@mike Likewise. I thoroughly enjoy a good exchange of ideas.
George Marian