Unpacking an Array of Arguments in PHP

unpacking an array of arguments in php

You can use call_user_func_array() to achieve that:

call_user_func_array("range", $args); to use your example.

Passing an Array as Arguments, not an Array, in PHP

http://www.php.net/manual/en/function.call-user-func-array.php

call_user_func_array('func',$myArgs);

Why the ...$args is adding value to sub-array? PHP

You are specifying that the function accept a variable number of arguments:

function withToken(...$arguments)

However, you pass ONE argument (an array). This doesn't expand into multiple arguments. You can attempt unpacking:

withToken(...[
'second' => 'second',
'third' => 'third'
]);

However you get:

Catchable fatal error: Cannot unpack array with string keys

This will work, but you won't get the string keys:

withToken(...[
'second',
'third'
]);

Same with this (no string keys):

call_user_func_array('withToken', [
'second' => 'second',
'third' => 'third'
]);

If you need string keys and values, stick with passing an array and not variable number of arguments.

Argument packing and unpacking when instantiating a new class instance in PHP

No you can't do it directly, you'll have to manually extract the values from the array and pass them to the constructor, or change it so that it accepts an array as argument.

You might take a look at call_user_func_array but I don't think you can use it with a constructor as you need an instance of the object to call one of its methods.

use PHP to unpack, process and pack array

I suppose what you're looking for is a way to call pack, which accepts arguments with an associative array as you have in your example. For this, we can use call_user_func_array which calls a function by its name and provides its arguments from a given array.

$bytes = "437XYZ25.011001DBEFORE                          ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);

// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";

// pack + write the result
$packTypes = ["a3", "x8", "C", "x4", "a32"];
$packFields = [$unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"]];

$packString = "";
$packArguments = [];
for ($i = 0; $i < count($packTypes); $i++){
$packString .= $packTypes[$i];
if ($packFields[$i] !== null){
// the null bytes don't use an argument
$packArguments[] = $packFields[$i];
}
}

// put packString as the first argument
array_unshift($packArguments, $packString);

$output = call_user_func_array("pack", $packArguments);

And $output would then be:

00000000  34 33 37 00 00 00 00 00  00 00 00 0c 00 00 00 00  |437.............|
00000010 41 46 54 45 52 20 20 20 20 20 20 20 20 20 20 20 |AFTER |
00000020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
00000030

Cannot unpack array with string keys

The problem is that the splat operator (array unpacking operator or ...) does not work with associative arrays. Example:

$array = [1, 2, 3];
$assoc = ["one" => 1, "two" => 2, "three" => 3];

var_dump(...$array); //Works
var_dump(...$assoc); //Doesn't work

You need to force an array to be numerically indexed in order to unpack it. You do this using array_values:

$values = array_values($q->fetch());
ModelController::execute(...$values);

Array values will ensure all values have a sequential numeric key.

Update

Starting PHP 8 there will be support for named arguments which will make both cases work. An example is documented in the proposed RFC for named arguments which says the following code should work starting PHP 8

$params = ['start_index' => 0, 'num' => 100, 'value' => 50];
array_fill(...$params);

Pass arguments from array in php to constructor

You can use the Reflection API:

  • ReflectionClass::newInstanceArgs — Creates a new class instance from given arguments.

Example:

$reflector = new ReflectionClass('Foo');
$foo = $reflector->newInstanceArgs(array('foo', 'bar'));


Related Topics



Leave a reply



Submit