8
<?php
function register_template(){
    print_r(func_get_args());
    # the result was an array ( [0] => my template [1] => screenshot.png [2] => nice template .. ) 

}

register_template(     # unkown number of arguments
    $name = "my template",
    $screenshot = "screenshot.png",
    $description = "nice template .. "
)
?>

BUT , I want the result array as $key => $value form , $key represents the parameter name.

2

11 Answers 11

15

PHP does not support an arbitrary number of named parameters. You either decide on a fixed number of parameters and their names in the function declaration or you can only get values.

The usual way around this is to use an array:

function register_template($args) {
    // use $args
}

register_template(array('name' => 'my template', ...));
Sign up to request clarification or add additional context in comments.

5 Comments

I don't need to use array as input
@web You will need to for what you're trying to accomplish.
.. I would to listen to your comment about my answer.
@Starx This isn't bad practice at all.
so with this method, how would you access the arguments. can you do something like echo $args['name']? or do you have to use something like func_get_args?
14

Wanted to do the same thing and wasn't completely satisfied with the answers already given....

Try adding this into your function ->

$reflector = new ReflectionClass(__CLASS__);
$parameters = $reflector->getMethod(__FUNCTION__)->getParameters();

$args = array();
foreach($parameters as $parameter)
{
    $args[$parameter->name] = ${$parameter->name};
}
print_r($args);

I haven't thought about trying to make this it's own function yet that you can just call, but might be able to...

2 Comments

This works flawlessly, thanks a lot. Managed to compress it to 5 lines brick-like code which I can now use everywhere I like. Not the prettiest solution, but it delivers and is robust.
keep in mind that use of Reflection is very slow and not advised for production
3

There is no such thing as a parameter name. frobnicate($a = "b") is not a call-with-parameter syntax, it's merely an assignment followed by a function call - a trick used for code documentation, not actually taken into account by the language.

It is commonly accepted to instead provide an associative array of parameters in the form: frobnicate(array('a' => 'b'))

Comments

2

Option A)

<?php

function registerTemplateA() {
    // loop over every variable defined in the global scope,
    // such as those you created there when calling this function
    foreach($GLOBALS as $potentialKey => $potentialValue) {
        $valueArgs = func_get_args();
        if (in_array($potentialValue, $valueArgs)) {
            // this variable seems to match a _value_ you passed in
            $args[$potentialKey] = $potentialValue;
        }
    }
    // you now have an associative array in $args
    print_r($args);
}

registerTemplateA($name = "my template", $screenshot = "screenshot.png", $description = "nice template");

?>

Option B)

<?php

function registerTemplateB() {
    // passing in keys as args this time so we don't need to access global scope
    for ($i = 0; $i < func_num_args(); $i++) {
        // run following code on even args
        // (the even args are numbered as odd since it counts from zero)
        // `% 2` is a modulus operation (calculating remainder when dividing by 2)
        if ($i % 2 != 0) {
            $key = func_get_arg($i - 1);
            $value = func_get_arg($i);
            // join odd and even args together as key/value pairs
            $args[$key] = $value;
        }
    }
    // you now have an associative array in $args
    print_r($args);
}

registerTemplateB('name', 'my template', 'screenshot', 'screenshot.png', 'description', 'nice template');

?>

Option C)

<?php

function registerTemplateC($args) {
    // you now have an associative array in $args
    print_r($args);
}

registerTemplateC(array('name' => 'my template', 'screenshot' => 'screenshot.png', 'description' => 'nice template'));

?>

Conclusion: option C is the best "for minimum code"

(Note: this answer is valid PHP code, with open and close tags in the correct places, tested using PHP 5.2.x and should run on PHP 4 also... so give it a try if you must.)

1 Comment

+1 For the proper way to manipulate a function with variable arguments. This is the proper method. See <php.net/manual/en/function.func-get-args.php for more info.
1

It's easy. Just pass the array as the parameter instead then later access it as $key => $value inside the function.

UPDATE

This was the best I could think of

$vars = array("var1","var2"); //define the variable one extra time here
$$vars[0] = 'value1'; // or use $var1
$$vars[1] = 'value2'; // or use $var2

function myfunction() {
    global $vars;
    $fVars = func_get_args();
    foreach($fVars as $key=>$value) {
       $fvars[$vars[$key]] = $value;
       unset($fvar[$key]);
    }
    //now you have what you want var1=> value1
}

myfunction(array($$vars[0],$$vars[1]));

I haven't tested it...BTW. But you should get the point

4 Comments

I don't need to use array as input
I dont see any easy way other than this
Lots of bad practice for no benefit at all. :)
@deceze, Yeah... I know my solution is really untidy.....but thats what OP wanted and that's what I gave ha ha
1

GET FUNCTION PARAMETERS AS MAP NAME=>VALUE

function test($a,$b,$c){

  // result map   nameParam=>value
  $inMapParameters=[];

   //get values of parameters
  $fnValueParameters=func_get_args();

  $method = new \ReflectionMethod($this, 'test');


      foreach ($method->getParameters() as $index=>$param) {

            $name = $param->getName();

            if($fnValueParameters[$index]==null){continue;}

            $inMapParameters["$name"]=$fnValueParameters[$index];
        }

}

Comments

1
class MyAwesomeClass
{
    public static function apple($kind, $weight, $color = 'green')
    {
        $args = self::funcGetNamedParams();
        print_r($args);
    }

    private static function funcGetNamedParams() {
        $func = debug_backtrace()[1]['function'];
        $args = debug_backtrace()[1]['args'];
        $reflector = new \ReflectionClass(__CLASS__);
        $params = [];
        foreach($reflector->getMethod($func)->getParameters() as $k => $parameter){
            $params[$parameter->name] = isset($args[$k]) ? $args[$k] : $parameter->getDefaultValue();
        }

        return $params;
    }
}

Let's test it!

MyAwesomeClass::apple('Granny Smith', 250);

The output:

Array
(
    [kind] => Granny Smith
    [weight] => 250
    [color] => green
)

1 Comment

this is a pretty cool solution. does anyone know of any drawbacks to using this method other than reflection being slow?
1

You can do it via get_defined_vars() but you should not forget this function return every variable in the scope of the function.

For example:

<?php

function asd($q, $w, $rer){
    $test = '23ew';
    var_dump(get_defined_vars());
}

asd("qweqwe", 'ewrq', '43ewdsa');
?>

Return:

array(4) {
  ["q"]=>
  string(6) "qweqwe"
  ["w"]=>
  string(4) "ewrq"
  ["rer"]=>
  string(7) "43ewdsa"
  ["test"]=>
  string(4) "23ew"
}

Comments

0

you can't, arguments are only positionnal. maybe you can send an array ?

<?php

function register_template(array $parameters) {
    var_dump($parameters);
}

register_template(# unkown number of arguments
    $name = "my template",
    $screenshot = "screenshot.png",
    $description = "nice template .. "
)


?>

1 Comment

Argument 1 passed to register_template() must be an array
0

Use

function register_template($args){
    print_r ( $args ); // array (['name'] => 'my template' ...
    extract ($args);

    print $name; // my template
    print $screenshot;
}

register_templete ( array (
 "name" => "my template",
 "screenshot" => "screenshot.png",
 "description" => "nice template.."
));

1 Comment

I don't need to use array as input
-3

use this :

foreach(func_get_args() as $k => $v)
    echo $k . " => " . $v . "<BR/>";

4 Comments

-1: this would output 0 => my template instead of the expected name => my template.
The way OP is calling the function is infact wrong; and there is no way you can get access the keys (name, screenshot etc) inside the called function, unless he passes the arguments as an associated array. func_get_args is therefore correct way if the way the function is called is corrected.
@Salman If an associative array is passed into the function, the above code will only result in one key and one value: $k = 0, $v = array(...).
that's true, and in that case the unkown number of arguments clause does not make sense anymore and instead you iterate over the associated array instead of func_get_args().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.