Editor, Themes, I18N: Use array_last() to read the last element of an array - #67
Draft
mukeshpanchal27 wants to merge 1 commit into
Draft
Editor, Themes, I18N: Use array_last() to read the last element of an array#67mukeshpanchal27 wants to merge 1 commit into
mukeshpanchal27 wants to merge 1 commit into
Conversation
… array. Replaces $array[ count( $array ) - 1 ] with the array_last() function added in PHP 8.5, for which core has shipped a polyfill in compat.php since 6.9.0. Besides avoiding the count() call, array_last() is correct for any array rather than only for gapless lists, and it states the intent directly. Two of the sites in pomo/plural-forms.php sit inside while loops, where count() was re-evaluated on every iteration. The site in block-supports/states.php is an assignment target, so it is instead restructured to build the rule and append it once, removing both the count() and a re-index write into a by-reference array. Props mukesh.
array_last() to read the last element of an array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Core reaches for the last element of an array by computing its length and subtracting one:
PHP 8.5 added
array_last()forexactly this, and core has shipped a polyfill for it in
wp-includes/compat.phpsince6.9.0. On PHP 8.5+ the native call replaces a userland function call, an integer op and a
hash lookup with a single VM handler.
The existing form has two further problems beyond speed:
count() - 1assumes keys are a gapless0..n-1sequence.
array_last()is correct for any array because it resolves the real last key.Every site changed here happens to hold a list today, but the assumption is invisible
and easy to break — anything that
unset()s an element upstream silently starts readingthe wrong index, or emits an undefined-index warning.
count( $x ) - 1describes an index calculation;array_last( $x )describes the thing actually wanted.array_first()/array_last()are already used elsewhere in core(
class-wp-walker.php:237,formatting.php:4580,class-wp-rest-widget-types-controller.php:507), so this follows an established conventionrather than introducing one.
Sites changed
src/wp-includes/class-wp-block-parser.phpadd_inner_block()— once per inner block, on every block parse.src/wp-includes/class-wp-theme-json.phpget_styles_for_block()element-name resolution.src/wp-includes/class-wp-theme-json.phpsrc/wp-includes/pomo/plural-forms.phpwhileloops —count()was re-evaluated on every iteration of the shunting-yard operator stack.src/wp-admin/includes/ajax-actions.phpwp_ajax_ajax_tag_search().src/wp-trackback.phpHottest site
public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) { - $parent = $this->stack[ count( $this->stack ) - 1 ]; + $parent = array_last( $this->stack );Loop sites
In
plural-forms.phpthe call sits in the body ofwhile ( ! empty( $stack ) ), so thecount()ran once per operator popped:while ( ! empty( $stack ) ) { - $o2 = $stack[ count( $stack ) - 1 ]; + $o2 = array_last( $stack );Related restructure —
block-supports/states.php:386This one is an assignment target, so
array_last()cannot apply. It is insteadrestructured to build the rule and append it once, which removes the
count()and are-index write back into a by-reference array:
Behaviour notes
array_last( array() )returnsnull, whereas$array[ count( $array ) - 1 ]on an empty array reads index-1and emits anundefined-array-key warning while evaluating to
null. The new form is strictlybetter-behaved. At every site changed here the array is already known non-empty
(
explode()always yields ≥1 element; thepomosites are guarded bywhile ( ! empty( $stack ) ); the parser stack is non-empty by construction), so noobservable behaviour changes.
pomo/and polyfill availability.pomo/is loaded outside the usual bootstrap insome tooling, so polyfill availability was checked before using it there:
pomo/po.phpalready calls
str_contains(),str_starts_with()andstr_ends_with()(lines 121, 521,524), all polyfilled in the same
compat.php. Usingarray_last()inpomo/thereforecarries no new dependency.
Testing instructions
vendor/bin/phpunit --filter '(PluralFormsTest|Tests_Blocks_wpBlockParser)'vendor/bin/phpunit --filter 'ThemeJson'vendor/bin/phpunit tests/phpunit/tests/block-supports/(e.g. Russian,
nplurals=3).check
innerBlocksstructure is unchanged.states.phppath).Verification done
php -lclean on all 6 files.vendor/bin/phpcs: 0 errors. One warning emitted, pre-existing and unrelated —plural-forms.php:1"Class file names should be based on the class name".--filter '(PluralFormsTest|Tests_Blocks_wpBlockParser)'→ OK (82 tests, 90 assertions)--filter 'ThemeJson'→ OK (312 tests, 637 assertions)