Description
Description
I was browsing through php's source code to look at how arrays work and noticed the following:
This code:
<?php
$a = array();
$a[-5] = "-5";
$a[] = "after -5";
behaves differently than this code:
<?php
$b = array(
-5 => "-5"
);
$b[] = "after -5";
Resulted in this output:
array(2) {
[-5]=>
string(2) "-5"
[0]=>
string(8) "after -5"
}
array(2) {
[-5]=>
string(2) "-5"
[-4]=>
string(8) "after -5"
}
But I expected this output instead:
array(2) {
[-5]=>
string(2) "-5"
[-4]=>
string(8) "after -5"
}
array(2) {
[-5]=>
string(2) "-5"
[-4]=>
string(8) "after -5"
}
I am not sure, if this is a bug or intended, so I wanted to create an issue regarding that.
The PR #3772 changed that appending to arrays would also work if the previous element has a negative index without defaulting to 0 in that case.
It did so by setting the default value for nNextFreeElement
from 0
to ZEND_LONG_MIN
, while also adding the following "guard clause" to the _zend_hash_index_add_or_update_i( )
function, which makes sure that the chosen index defaults to 0
if it's still at ZEND_LONG_MIN
and the element should be put at the next index. https://github.com/php/php-src/blob/master/Zend/zend_hash.c#L1027-L1029.
But it did not change that for the _zend_empty_array
constant: https://github.com/php/php-src/blob/master/Zend/zend_hash.c#L258. Because of that, the following if statement is always false for empty arrays since (any_negative_key >= 0) == false
: https://github.com/php/php-src/blob/master/Zend/zend_hash.c#L1110-L1112.
My question is, is this intended? Because it looks like a bug to me, especially since that "guard clause" would ensure that running $a[] = ""
on an empty array, would still use index 0
.
But I am not familiar with the PHP internals, so I might have completely missed something. So if there is a reason for this behaviour or why _zend_empty_array
's nNextFreeElement
can't start at ZEND_LONG_MIN
, I would be happy to know why!
PHP Version
PHP 8.2.3
Operating System
No response