Make WordPress Core

Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#51108 closed defect (bug) (fixed)

PHP 8: Incorrect wp_localize_script() usage in wp-admin/edit-form-blocks.php

Reported by: sergeybiryukov's profile SergeyBiryukov Owned by: sergeybiryukov's profile SergeyBiryukov
Milestone: 5.6 Priority: normal
Severity: normal Version:
Component: Editor Keywords: php8
Focuses: Cc:

Description

Background: #25280, #29722, #48528.

The $l10n parameter of wp_localize_script() is documented as an array, however, it's also technically possible to pass a string, with the only difference that it won't run through html_entity_decode( ..., ENT_QUOTES, 'UTF-8' ), as previously noted in comment:9:ticket:29722.

One notable instance in core that does this is in wp-admin/edit-form-blocks.php:

$meta_box_url = add_query_arg(
	array(
		'post'                  => $post->ID,
		'action'                => 'edit',
		'meta-box-loader'       => true,
		'meta-box-loader-nonce' => wp_create_nonce( 'meta-box-loader' ),
	),
	$meta_box_url
);
wp_localize_script( 'wp-editor', '_wpMetaBoxUrl', $meta_box_url );

This is now causing a warning in PHP 8.0 Beta 2:

Warning: Only the first byte will be assigned to the string offset in wp-includes/class.wp-scripts.php on line 492

wp_localize_script() should probably be updated to better handle scalar values, as per the tickets linked above.

To solve the immediate issue though, wp-admin/edit-form-blocks.php should use wp_add_inline_script() instead, as it already does for other scripts a few lines earlier. That would also be in line with comment:45:ticket:25280.

Change History (4)

#1 @SergeyBiryukov
4 years ago

  • Owner set to SergeyBiryukov
  • Resolution set to fixed
  • Status changed from new to closed

In 48841:

Editor: Use wp_add_inline_script() instead of wp_localize_script() to pass the _wpMetaBoxUrl value to the wp-editor script.

This fixes a PHP 8 "Only the first byte will be assigned to the string offset" warning on Edit Post screen.

The correct usage of wp_localize_script() is to pass an array of data, not a string.

Fixes #51108.

#2 follow-up: @azaozz
4 years ago

Right, using wp_add_inline_script() is better in this case.

However, where is that warning coming from? For back-compat reasons $wp_scripts->localize() does:

if ( is_array( $l10n ) ...
...
foreach ( (array) $l10n as $key => $value )
...

I.e. it supports passing a string as mentioned in the ticket, and the string should be cast to array.

Does casting to array work in PHP 8.0?

Last edited 4 years ago by azaozz (previous) (diff)

This ticket was mentioned in Slack in #core by sergey. View the logs.


4 years ago

#4 in reply to: ↑ 2 @SergeyBiryukov
3 years ago

Replying to azaozz:

However, where is that warning coming from?

For reference, the warning comes from the last line of that loop:

foreach ( (array) $l10n as $key => $value ) {
	if ( ! is_scalar( $value ) ) {
		continue;
	}

	$l10n[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
}

The (array) casting here only affects the foreach operator itself, but does not change the $l10n variable, which is still a string, so the $l10n[ $key ] = ... assignment produces a warning.

Note: See TracTickets for help on using tickets.