compuphys
compuphys

Reputation: 1377

How to pass multiple function parameters in an array in php?

I want to pass multiple parameters to a function in an array. The parameters themselves are arrays of strings.

I have a function called new_action(), which I call in the following way:

new_action(array('actions' => array('ACTION1','ACTION2'), 'tables' => array('table1','table2')));

and that function looks like this:

public function new_action($params=array()) {
  $tables = array();
  $actions = array();

  if(count($params)) {
    foreach($params as $k => $v) {
      $tables  = ($k == 'tables')  ? $v : array();
      $actions = ($k == 'actions') ? $v : array();
    }

    // Do useful stuff with the variables here ...
    var_dump($tables);
    var_dump($actions);

    // ======== ACTUAL OUTPUT: ========
    // array(0) { }
    // array(0) { }

    // ======== EXPECTED OUTPUT: ========
    // array(2) { [0]=> string(6) "table1" [1]=> string(6) "table2" }
    // array(2) { [0]=> string(7) "ACTION1" [1]=> string(7) "ACTION2" }
  } 
}

As you can see, the value of $v inside the loop (the array of strings) is never being copied to the variable $tables or $actions outside the loop.

I think this is most likely a scope problem but looking at answers to other questions similar to this hasn't elucidated the solution for me.

How do I refactor the code so that I can access those arrays stored in $v for each $k outside the foreach loop?

Upvotes: 0

Views: 823

Answers (3)

Markus Zeller
Markus Zeller

Reputation: 9153

The values are empty, because with the foreach you are overwriting existing values.

You can even write it more simple and use array shorthand syntax with brackets for better readability.

The null coalesce operator is syntactic sugar to avoid writing isset() and also is ternary. If it is set, it will return its contents, otherwise set to an empty array.

new_action(['actions' => ['ACTION1', 'ACTION2'], 'tables' => ['table1', 'table2']]);

function new_action($p = array()): void {
    $tables  = $p['tables']  ?? [];
    $actions = $p['actions'] ?? [];

    var_dump($tables);
    var_dump($actions);
}

array(2) { [0] => string(6) "table1" [1] => string(6) "table2" }
array(2) { [0] => string(7) "ACTION1" [1] => string(7) "ACTION2" }

Upvotes: 1

Cadu De Castro Alves
Cadu De Castro Alves

Reputation: 647

You actually don't need the foreach to get that output:

public function new_action($params = array()) {
  $tables = array_key_exists('tables', $params) ? $params['tables'] : [];
  $actions = array_key_exists('actions', $params) ? $params['actions'] : [];

  // Do useful stuff with the variables here ...
  var_dump($tables); // Outputs => array(2) { [0]=> string(6) "table1" [1]=> string(6) "table2" }
  var_dump($actions); // Outputs => array(2) { [0]=> string(7) "ACTION1" [1]=> string(7) "ACTION2" }
  } 
}

Upvotes: 1

cOle2
cOle2

Reputation: 4784

Your code is overwriting what was previously set because you are setting the values to array() when the key doesn't match tables or actions. So when $k == 'tables', $actions gets set back to an empty array.

Instead of the ternary operator, basically an if/else, refactor to just an if if you want to keep the loop:

foreach($params as $k => $v) {
        if ($k == 'tables') {
            $tables = $v;
        }
        if ($k == 'actions') {
            $actions = $v;
        }

    }

Or it can be condensed a bit by explicity checking for those keys at the start instead of looping:

function new_action($params=array()) {

    $tables = isset($params['tables']) ? $params['tables'] : array();

    $actions = isset($params['actions']) ? $params['actions'] : array();

    // Do useful stuff with the variables here ...
    var_dump($tables);
    var_dump($actions);

}

Upvotes: 2

Related Questions