Edit report at https://bugs.php.net/bug.php?id=78188&edit=1
ID: 78188
Updated by: girgias@php.net
Reported by: girgias@php.net
-Summary: Make unpack return a 0 indexed array instead of a 1
indexed array
+Summary: Improve unpack doc, explain why it's a 1 indexed
array, etc.
-Status: Feedback
+Status: Open
-Type: Feature/Change Request
+Type: Documentation Problem
Package: Unknown/Other Function
-PHP Version: Next Major Version
+PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
> If this is the main reason for your request then what if I told you that you can easily skip
> the first element?
It is kind of the main reason but mostly I didn't get why it would start at 1 instead of 0. The
implementation explanation makes sense.
However just to confirm if all unpack formats are named then it does behave as a 0 indexed array,
right?
So in a way its the behavior of numerical string keys as array keys which is jumping out.
I'll change that to a doc bug as the named keys in the return array isn't documented
> [...] but perhaps the missing link for you is the magic "return_value" variable.> That's where return values from functions go, and unpack() uses it like
That was indeed the missing link. :)
Previous Comments:
------------------------------------------------------------------------
[2019-06-20 14:34:20] requinix@php.net
> This makes it unusable with list()
If this is the main reason for your request then what if I told you that you can easily skip the
first element?
list(, $A, $B) = unpack("c2", "\x41\x42");
That aside, the behavior is related to how unpack handles a named repeated argument:
<?php
$binarydata = "\x04\x00\xa0\x00";
$array = unpack("c2chars/nint", $binarydata);
print_r($array);
?>
Array
(
[chars1] => 4
[chars2] => 0
[int] => 40960
)
Note that PHP starts with "chars1". When an argument is unnamed PHP follows the same
process and forces it to be numbered, but without the name it results in the string "1" -
which is a number and so forced to the integer 1 when used as an array key.
> how and when the array is returned from the function,
Documentation I don't have, but perhaps the missing link for you is the magic
"return_value" variable. That's where return values from functions go, and unpack()
uses it like
array_init(return_value);
(to initialize an empty array) and
zend_array_destroy(Z_ARR_P(return_value));
RETURN_FALSE;
(RETURN_FALSE is a macro to set return_value=false and return) and
add_assoc_stringl(return_value, n, &input[inputpos], len);
------------------------------------------------------------------------
[2019-06-20 13:57:41] girgias@php.net
Description:
------------
Currently unpack returns an array which starts with index 1.
This makes it unusable with list() directly as list() only works with 0 indexed arrays so to
destructure an unpack array it first needs to go through array_values().
As this is a BC break I'm marking this Feature Request for next Major.
Sidenote, I tried to understand how PHP implements unpack but I'm confused as to how and when
the array is returned from the function, if anyone can point me to some up to date documentation
about the Zend engine that covers this bit that would be great as currently, phpinternalsbook does
not cover Arrays in PHP 7
This may be partially related to #54734
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78188&edit=1