Opened 22 months ago
Last modified 3 months ago
#55105 reopened feature request
Introduce a polyfill for `array_is_list()`.
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | 6.5 | Priority: | normal |
Severity: | minor | Version: | |
Component: | General | Keywords: | has-patch has-unit-tests |
Focuses: | Cc: |
Description
PHP 8.1 introduces a new function, array_is_list()
.
The function determines whether an array's keys consist of consecutive numbers from 0
to count( $arr ) - 1
.
Including a polyfill will allow developers to take advantage of the new function.
Notes
- A list must start from an offset of 0.
array( 2 => 'one', 3 => 'two' );
will returnfalse
. - An empty array will return
true
.
References
- PHP Manual: array_is_list
- PHP RFC: Add array_is_list
- 3v4l.org: Examples
Attachments (1)
Change History (16)
This ticket was mentioned in PR #2289 on WordPress/wordpress-develop by costdev.
22 months ago
#2
- Keywords has-patch has-unit-tests added
#4
@
22 months ago
@costdev sorry if I am wrong, I think on line 500 it will be if( $k !== $i ) then return false.
#5
follow-up:
↓ 6
@
22 months ago
Hi @rafiahmedd, thanks for reviewing the PR! I left a comment there about pre-incrementation vs post-incrementation.
#6
in reply to:
↑ 5
@
22 months ago
Replying to costdev:
Hi @rafiahmedd, thanks for reviewing the PR! I left a comment there about pre-incrementation vs post-incrementation.
@costdev thank you brother 😊
#7
@
22 months ago
I'm wondering why this function should be polyfilled. Can you give one or more examples of code in WordPress which would benefit from the function being available ?
If there are no current usecases for this function in Core, the function shouldn't be introduced.
#9
@
21 months ago
@jrf I tried to find a use case prior to writing the polyfill. I couldn't find one. Examples online seem to literally just reiterate what the function does, without providing use cases, and vaguely referring to "PHP security vulnerabilities caused by arrays that are not in order", without mentioning array_values()
once.
Why did I write it then?
I'd just reviewed and written tests for some of the polyfills introduced in 5.9, and I wasn't quite done with my polyfilling-spree. It's there, with unit tests, if use cases are found.
As we're still early enough in the release cycle, I'll leave this open in case someone sees value in introducing this polyfill to Core. If there are none provided as we approach feature freeze, I'll go ahead and close as maybelater
, or punt to 6.1 if use cases are actively being discussed.
#10
@
20 months ago
- Version 5.9 deleted
Feature requests don't require a version, so I have removed that.
@costdev As there hasn't been any additional discussion, are you able to decide whether you'd like to have another go in a future milestone or close this as maybelater?
#11
follow-up:
↓ 15
@
20 months ago
- Keywords dev-feedback removed
- Milestone 6.0 deleted
- Resolution set to maybelater
- Status changed from new to closed
Yeah, let's close this one as maybelater
so it can be picked up, with unit tests, if use cases are found.
For some futureproofing, I'll close the PR and upload a .diff
to the ticket, which will include an additional dataset for array( NAN )
.
Some history for contributors who may look at this in future:
- The patch uses
foreach ( $arr...
instead ofarray_keys( $arr )
orarray_keys($arr) === range(count($arr)-1)
to avoid creating new arrays unnecessarily. This means only one pass over the array, and is in line with the example given in the RFC's Proposal section. - An early return for an empty array is not included because an empty array will skip on the
foreach()
and returntrue
. - An alternative implementation used by Symfony has an early return on
$array === array_values($array)
. The performance improvement from this early return is negligible, but importantly, performance is inconsistent across different versions of PHP, so I think the current implementation is the simplest and most effective polyfill forarray_is_list()
.
20 months ago
#12
Closed in favour of 55105.diff.
#13
@
14 months ago
Some random related thoughts...
See also: wp_is_numeric_array()
& rest_is_array()
for similar but different examples of functions in WordPress that are documented to imply their intention may have been to mimic the behavior of array_is_list()
but perhaps a consult from @rmccue would be helpful?
The above helper function(s) @return bool Whether the variable is a list
but do not enforce @costdev's first point:
A list must start from an offset of 0
(emphasis, mine... but I think I agree?)
While a bunch of other programming languages explicitly define & strictly enforce "List" and "Array" as different things (C, Java, Python, etc...) neither PHP nor WordPress do currently.
I think that means it is safe to suggest that WordPress functions named like wp_parse_list()
and wp_list_*()
– and the WP_List_Util()
class – largely imply that they are intended to work with either arrays or objects. Similarly, only the REST API (and later the Meta API via default values in get_metadata_default()
) have experienced a need for identifying whether a variable value was a numerically indexed array that starts with 0 and does not omit any subsequent integers as keys until the final key.
Without speculating too deeply, PHP core is trending towards becoming more strict (hence more static), so perhaps someday a "List" could be a more explicitly defined thing, and it may behoove WordPress core contributors to have a plan for that and decide whether to:
- Keep down the path of generalized "lists" as arrays or objects
- Add to the global namespace
list
functions & classes that mean whatarray_is_list()
means
#14
@
3 months ago
The Performant Translations feature plugin is one project that uses array_is_list()
(ref) and would require this polyfill upon core merge.
#15
in reply to:
↑ 11
@
3 months ago
- Milestone set to 6.5
- Resolution maybelater deleted
- Status changed from closed to reopened
Replying to costdev:
Yeah, let's close this one as
maybelater
so it can be picked up, with unit tests, if use cases are found.
It is worth noting that polyfills for array_key_first()
and array_key_last()
were added in [52038] / #45055 even without being used by WordPress core.
I believe the benefit here is pretty much the same as in that ticket:
Including a polyfill would allow developers to take advantage of the new functions and write consistent code regardless of a site's PHP version.
Now that WordPress has PHP 8.1 compatibility (with exceptions), I think it's time to reconsider this.
With 6.4 Beta 1 coming in a few days, moving to 6.5 for discussion.
Trac ticket: https://core.trac.wordpress.org/ticket/55105