PHP Native JSON Extension Now Required

The PHP native JSON extension has been bundled and compiled with PHP by default since 5.2.0 (2006). However, a significant number of PHP installs did not include it. In order to ensure a consistent experience for JSON related functionality in all supported versions of PHP, WordPress Core has historically included a large number of workarounds, functions, and polyfills.

In 2011 (WordPress 3.2), an attempt was made to remove JSON related compatibility code. However, it was discovered that a fair number of distributions were still missing the PHP JSON extension by default, and the removed code was restored to ensure compatibility.

In WordPress 5.2, the minimum version of PHP supported was raised from 5.2.6 to 5.6.20. In the 8 year period since the last attempt was made to encourage use of the PHP native JSON extension, the number of distributions with this extension disabled has significantly decreased.

Because of this, the PHP native JSON extension is now required to run WordPress 5.3 and higher.

To prevent compatibility issues, a site that does not have the PHP native JSON extension enabled will see an error message when attempting to upgrade to WordPress 5.3. The update will be cancelled and the site will remain on the current version (see [46455]). This is to prevent potential compatibility issues on servers running custom PHP configurations.

Here’s a summary of what has changed.

Deprecated

The following functions and classes will remain in the code base, but will trigger a deprecated warning when used (see [46205]):

  • The Services_JSON and Services_JSON_Error classes and all methods
  • The wp-includes/class-json.php file
  • The (private) _wp_json_prepare_data() function

Removed

The following functions, and classes have been removed entirely from the code base (see the [46208] changeset):

  • json_encode() function polyfill
  • json_decode() function polyfill
  • _json_decode_object_helper() function polyfill
  • json_last_error_msg() polyfill
  • JsonSerializable interface polyfill
  • $wp_json global variable
  • JSON_PRETTY_PRINT constant polyfill
  • JSON_ERROR_NONE constant polyfill

Unchanged

The wp_json_encode() function will remain with no intention to deprecate it at this time. This function includes an extra sanity check for JSON encoding data and should still be used as the preferred way to encode data into JSON.

For more information about these changes, check out #47699 on Trac and the relevant changesets ([46205], [46206], [46208], [46377], and [46455]).

Props @jrf & @jorbin for peer review.

#5-3, #dev-notes, #php

WP 5.3: Introducing the spread operator

In WordPress 5.3, the PHP 5.6 spread operator has been introduced to WordPress in a number of places.

Using the spread operator allowed for simplifying the code and improves performance – both in speed as well as memory use -, especially as it has been introduced in a number of functions which are used a multitude of times during every single pageload, such as current_user_can() and add_query_arg().

For full details, see Trac ticket #47678.

Impact on plugins/themes

Most plugins and themes should see no impact of these patches, other than the improved performance.

However, if your plugin/theme is one of the limited number of plugins and themes which extends one of the below listed classes and overloads any of the listed methods, you will need to take action.

What to do if your plugin/theme is affected

In nearly all cases, WP 5.3 has added a new parameter to the function signature using the spread operator. This allows for an easy transition as you can adjust the function signature of the method overloading it to do the same.
You may also want to adjust the code within the overloaded method to get the same performance benefits as the parent method.

See the relevant patches linked below for the full details of the change to each method and for inspiration.

Adding the extra argument will allow your plugin/theme to be compatible with both WP 5.3 and older WP versions, though it does raise the minimum PHP requirement for your plugin/theme to PHP 5.6.
Make sure you annotate this in the readme.txt!

In only one case – wpdb::prepare() -, WP 5.3 has changed an existing parameter.
In the exceptional situation that you would be overloading that method, you will need to make a choice whether you want to continue supporting older WP versions or to set the minimum WP version to WP 5.3.
If you set the minimum WP version to WP 5.3, you need to change the function signature of the overloading method to match the new function signature in WP 5.3 and you may also want to simplify some code in your method too.
If you want to continue to support older WP versions, you will need two versions of the class overload and an if/else toggle to load the correct one depending on the WP version being used.
Note: this really only applies to overloaded wpdb::prepare() methods. There is no need to do this if you overload any of the other affected methods.

What will break if I don’t make the change to my plugin/theme

Nothing. The world will keep turning as it did before.

You may get some complaints from end-users that they are seeing PHP warnings about a mismatched function signature in their PHP error logs, but other than that, all should still work as before.

This is not to say that you shouldn’t update your plugins/themes… You should.
It is just that if you don’t have time to do it right away, you don’t need to worry that your plugin/theme will be bringing sites down.

List of affected classes:

List of affected test classes:

#fortheloveofcode, #modernizewp, #5-3, #dev-notes, #php

PHP Coding Standards Changes

This is a follow-up to several changes proposed a few months ago.

While reading these changes, it’s important to keep in mind that they only apply to WordPress Core: you can (and should) choose practices that best suits your development style for your own plugins and themes. The coding standards are intentionally opinionated, and will always lean towards readability and accessibility over being able to use every possible language feature.

Closures (Anonymous Functions)

There was quite a lot of discussion around this proposal, particularly with regards to allowing closures as hook callbacks. Thank you everyone for your input, and for keeping disagreements respectful. 🙂

We do need a decision, however, and there were several key points that led to this:

  • It’s currently difficult to remove closures as hook callbacks. #46635 has several interesting proposals to address this in an entirely backward compatible manner.
  • While WordPress Core should strive to allow any callback to be unhooked, plugins have no such restriction.
  • The WordPress JavaScript Coding Standards allow for closures to be used, we should be aiming to bring the PHP standards in line with that.
  • The broader PHP world has embraced closures for many years, and have found ways to use them responsibly. We shouldn’t ignore PHP usage outside of WordPress.

With these points in mind, a conservative, but practical step is to allow closures as function callbacks, but not as hook callbacks in Core. Ultimately, we should be able to allow any sort of complex callback to be attached to hooks, but the Core APIs aren’t quite ready for it yet.

Coding Standards Change

Where appropriate, closures may be used as an alternative to creating new functions to pass as callbacks.

Closures must not be passed as filter or action callbacks, as they cannot be removed by remove_action() / remove_filter() (see #46635 for a proposal to address this).

Short Array Syntax

A little less controversial, but still with varying opinions, was the proposal to require short array syntax ( [ 1, 2, 3 ] ) instead of long array syntax ( array( 1, 2, 3 ) ) for declaring arrays.

While I’m personally partial to short array syntax, there were two particularly convincing arguments for using long array syntax:

  • It’s easier to distinguish from other forms of braces, particularly for those with vision difficulties.
  • It’s much more descriptive for beginners.

So, this change to the coding standards is the opposite of what was originally proposed, but is ultimately the more inclusive option.

Coding Standards Change

Arrays must be declared using long array syntax in WordPress Core.

Short Ternary Operator

The original proposal was to allow the short ternary operator, but this change reverses that. There’s a good argument that it looks too much like the null coalesce operator, especially as they perform different functions.

Take the following example from Core:

$height = isset( $data['height'] ) ? $data['height'] : 0;

It’s not possible to reduce this line with the short ternary operator, but it can be trivially reduced with the null coalesce operator:

$height = $data['height'] ?? 0;

The vast majority of other ternary operators in Core (which don’t have an isset() test) look something like this:

$class = $thumb ? ' class="has-media-icon"' : '';

This also can’t be reduced using the short ternary operator.

As the null coalesce operator is a useful addition (which we’ll be able to use once the minimum PHP version bumps to 7+), whereas the short ternary operator can only be used in a handful of cases in Core, it’s better to avoid the potential confusion, and not use the short ternary operator.

Coding Standards Change

The short ternary operator must not be used.

Assignments Within Conditionals

Particularly when there are multiple conditions, it can be quite difficult to spot assignments occurring in a conditional. This arguably falls under the Clever Code guidelines, but hasn’t been formalised.

I got a little ahead of myself with this one, and have already removed all assignments in conditionals from Core. Adding this change to the standard formalises the practice.

Coding Standards Change

Assignments within conditionals must not be used.

#php, #wpcs

Coding Standards Updates for PHP 5.6

With the minimum PHP version increasing to 5.6 as of WordPress 5.2, now’s a good time to be reviewing the WordPress Coding Standards.

Here is a set of changes that I’d like to propose.

Anonymous Functions (Closures)

Anonymous functions are a useful way to keep short logic blocks inline with a related function call. For example, this preg_replace_callback() call could be written like so:

$caption = preg_replace_callback(
	'/<[a-zA-Z0-9]+(?: [^<>]+>)*/',
	function ( $matches ) {
		return preg_replace( '/[\r\n\t]+/', ' ', $matches[0] );
	},
	$caption
);

This improves the readability of the codebase, as the developer doesn’t need to jump around the file to see what’s happening.

Coding Standards Proposal

Where the developer feels is appropriate, anonymous functions may be used as an alternative to creating new functions to pass as callbacks.

Anonymous functions must not be passed as filter or action callbacks in WordPress Core, as they cannot be removed by remove_action() / remove_filter() (see #46635 for a proposal to address this). Outside of Core, developers may pass anonymous functions as filter or action callbacks at their own discretion.

Namespaces

Namespaces are a neat way to encapsulate functionality, and are a common feature in modern PHP development practices. As we’ve discovered in the past, however, introducing namespaces to the WordPress codebase is a difficult problem, which will require careful architecture and implementation.

Side note: there’s currently no timeline for introducing namespaces to WordPress Core, expressions of interest are welcome. 🙂

Coding Standards Proposal

At this time, namespaces must not be used in WordPress Core.

Short Array Syntax

Rather than declaring arrays using the array( 1, 2, 3 ) syntax, they can now be shortened to [ 1, 2, 3 ]. This matches how arrays are declared in the WordPress JavaScript Coding Standards.

To allow for plugins and themes that support older versions of WordPress, I’d like to propose that WordPress Core switches to short array syntax immediately, but plugins and themes may choose which they use. A future iteration would make short array syntax a requirement.

Coding Standards Proposal

Arrays must be declared using short array syntax in WordPress Core. Arrays may be declared using short array syntax outside of Core.

Short Ternary Syntax

A fairly common pattern when setting a variable’s value looks something like this:

$a = $b ? $b : $c;

The short ternary syntax allows this to be shortened, like so:

$a = $b ?: $c;

It’s important to note that this is different to the null coalesce operator, which was added in PHP 7. If $b is undefined, the short ternary syntax will emit a notice.

Coding Standards Proposal

Short ternary syntax may be used where appropriate.

Assignments within conditionals

While this isn’t directly related to the PHP version bump, I’d like to propose disallowing assignments within conditionals. Particularly when there are multiple conditions, it can be quite difficult to spot assignments occurring in a conditional. This arguably falls under the Clever Code guidelines, but hasn’t been formalised.

For example, this if statement would be written like so:

$sticky_posts = get_option( 'sticky_posts' );
if ( 'post' === $post_type && $sticky_posts ) {
	// ...
}

Coding Standards Proposal

Assignments within conditionals are not allowed.

Other New Features

Any other new features available in PHP 5.6 can be used, though we should continue to carefully consider their value and (in the case of newer PHP modules) availability on all hosts.


How do you feel about these changes? Are there other changes related to PHP 5.6 that you’d like to suggest?

#php, #wpcs

PHP Meeting Recap – December 17th

This recap is a summary of our previous PHP meeting. It highlights the ideas and decisions which came up during that meeting, both as a means of documenting and to provide a quick overview for those who were unable to attend.

You can find this meeting’s chat log here.

Chat Summary

  • The meeting focused on the individual pieces that are left to complete so that the most essential Servehappy parts can become part of the WordPress 5.1 release (planned schedule has first Beta set at January 10th).
  • For the fatal error recovery mechanism (see #44458 or GitHub PR for development) the following steps are needed:
    • Add support for recovering errors by the theme by pausing it. It was determined before that the admin can work without an active theme, so implementation of this should be straightforward based on the existing code that already handles this for plugins.
    • In addition to displaying a note in the frontend when an error occurs (customizable via a php-error.php drop in), an email with the same message should be sent to the admin email address.
    • @schlessera will take care of implementing these two remaining tasks.
    • The multisite team will furthermore have an additional look at the existing implementation of multisite support.
  • A few updates are required for the Update PHP page:
    • Instead of having the content coming from the editor, it should be hardcoded and displayed via a template so that translation of the content is more streamlined and can happen via GlotPress. Furthermore it makes it a quicker process to add visual assets to the page later. @flixos90 is taking care of this.
    • The page slug needs to be changed from upgrade-php to update-php, as previously discussed, including a redirect. @sergeybiryukov has already completed this work.
  • For the actual notice in core itself, a few tweaks need to be added.
    • The version numbers need to be updated for WordPress 5.1.
    • The link URL to the page needs to be updated to account for the slug change.
    • The link URL needs to be customizable via both an environment variable (to be set by hosting providers) and a filter (for later adjustments in the codebase).
    • @flixos90 is working on these updates as part of #45686.
  • In the Servehappy API endpoint, the recommended PHP version should be set to 7.3, and the lowest acceptable version should be set to 5.6 to account for the future version bump. On any version below that, WordPress users will see a warning. Furthermore the information on official PHP version support needs to be updated as both PHP 5.6 and 7.0 are no longer support (or will be in very few days). This update has as of now been committed already as well.
  • During the work on the Meta changes in the aftermath of the meeting, it came up that adjusting version numbers exposed by wordpress.org should become a more straightforward process that can happen in a central location. This part is not crucial to have prior to WordPress 5.1, but is a minor tweak to make maintenance simpler in the future.
  • Still left is enhancing the page content with visual assets. It was agreed that these should not contain any language-dependent text. Among the suggestions were:
    • a diagram of how the server hardware, PHP, and WordPress relate to each other
    • a timeline of PHP version history
  • None of the attendees felt capable or had availability to work on such visual assets. If you can help with this over the next couple weeks, please let us know in the comments or the #core-php channel on Slack.
  • Due to the holidays in many parts of the world, the meetings in the next two weeks are cancelled. Finishing the features for WordPress 5.1 is a high priority though, and communication should continue asynchronously as needed. The next official meeting will take place only a few days before the intended 5.1 Beta release, so at that point everything should preferably be good to be merged.

Next week’s meeting

  • Next meeting will take place on Monday, January 7th, 2019 at 16:00 UTC in #core-php.
  • Agenda: Finalize remaining WordPress 5.1 work in order to be ready in time for the first Beta (Janurary 10th).
  • If you have suggestions about this but cannot make the meeting, please leave a comment on this post so that we can take them into account.

#php, #servehappy, #summary

PHP Meeting Recap – December 3rd

This recap is a summary of our previous PHP meeting. It highlights the ideas and decisions which came up during that meeting, both as a means of documenting and to provide a quick overview for those who were unable to attend.

You can find this meeting’s chat log here.

Chat Summary

  • @drewapicture announced that he’d start working on a proposal to add modern PHP best practices to the core handbook at WCUS contributor day.
  • The discussion about feature flags from the previous week was picked up again, particularly regarding the trade-offs of relying on a (network) option vs relying on a constant or environment variable.
    • Since some of the processes to be tested are executed very early in the WordPress bootstrap process, a variable that can be set in wp-config.php or earlier should be used. There possibly could be a wrapper function to access that value, including a filter that would allow adjusting the constant value dynamically by code that would run later.
    • WP-CLI could also be used to “more dynamically” set the constants.
    • It was mostly agreed that the Beta Tester plugin should somehow incorporate the feature flags functionality, in favor of core, at least initially.
    • Eventually, it was summarized that the topic should get picked up again later, as the WSOD protection mechanism (see #44458) is not blocked by this and should move forward.
  • Further conversations on the current state of the project will happen at WCUS, with the results being published in a recap. The meeting on December 10th is cancelled because of WCUS and related travel.

Post-WCUS Update

  • As mentioned during the State of the Word, WordPress core aims to raise the minimum required PHP version to 5.6 by April 2019, and to 7 by end of 2019 – a great success for the ecosystem and the Servehappy initiative.
  • A conversation between members of the core, community and hosting teams happened during contributor day, planning the steps ahead for both Servehappy and the overall Site Health project that it is part of. A detailed summary of this will be published separately.
  • The goal for the initial parts of Servehappy is to release them ahead of the PHP version bump, likely as part of WordPress 5.1. Due to the intended version bump, the core notice should be displayed on all PHP versions below 5.6, contrary to the originally intended idea of only targeting 5.2 initially.

Next week’s meeting

#core-php, #php, #servehappy, #summary

PHP Meeting Recap – November 26th

This recap is a summary of our previous PHP meeting. It highlights the ideas and decisions which came up during that meeting, both as a means of documenting and to provide a quick overview for those who were unable to attend.

You can find this meeting’s chat log here.

Chat Summary

  • @schlessera introduced the idea of using the concept of “feature flags” to be able to commit experimental code to be tested into trunk without immediately affecting everyone by default. Features hidden behind these feature flags would be opt-in through a mechanism like a setting in wp-config.php. The WP Beta Tester plugin could maybe be updated to provide a graphical interface to enable such feature flags.
  • The general format for feature flags in the wp-config.php could be something like the following:
    define( 'WSOD_PROTECTION', getenv( 'WSOD_PROTECTION ) || false );
  • This allows for direct hardcoding of the value, as well as for passing it in via the server environment.
  • Discussion revolved around whether such a “feature flag” system would actually improve anything. For code to be considered “committable” to trunk under a feature flag, conditions would probably be the very same than for it to be committable to trunk directly.
  • @nerrad is concerned about the code churn that such feature flags could add to Core development.
  • @sergeybiryukov is concerned that feature flags would create a new precedent in WordPress and would prefer to have us either commit the required hooks into Core to provide WSOD protection through a plugin, or to iterate directly in trunk as this has been done before the advent of feature plugins.
  • An alternative approach would be to make branches available through the WP Beta Tester plugin. However, branches are hard to keep in sync with trunk, especially in SVN.
  • @afragen will experiment with changes to the WP Beta Tester plugin to see how feature flags or branches could be handled.

Post-meeting update

Next week’s meeting

  • Next meeting will take place on Monday, December 3rd, 2018 at 15:00 UTC in #core-php.
  • Agenda: WCUS in-person opportunities planning.
  • If you have suggestions about this but cannot make the meeting, please leave a comment on this post so that we can take them into account.

#core-php, #php, #summary

PHP Meeting Recap – November 19th

This recap is a summary of our previous PHP meeting. It highlights the ideas and decisions which came up during that meeting, both as a means of documenting and to provide a quick overview for those who were unable to attend.

You can find this meeting’s chat log here.

Chat Summary

  • @joyously asked about the current state of Tide. @flixos90 added that he is not clear on where it currently stands, but once it is open for projects like Servehappy to integrate with it, it would make a great use-case. Automating the PHP version compatibility might be more reliable in the long run than requiring plugin/theme authors to manually keep that information up to date.
  • The topic of having a range of supported PHP versions for each plugin was discussed throughout the meeting.
  • Information of a maximum supported version of course helps the user to determine its compatibility, generally. However, it can also have negative implications on the PHP efforts: In case the maximum supported version information is not accurate, it will make site owners hesitant from updating PHP, for no reason. Particularly since this conflicts with the project’s goal, caution is required.
  • Neither the plugin/theme author nor an automated code-sniffing based tool can reliably provide compatibility information. Arguably, the latter will end up with more accurate results in the long run, but it still will include many false positives (or false negatives).
  • Due to this problem, there was mostly consensus that no tested up to PHP version should be exposed at this point. While both the minimum and maximum versions are not reliable, the maximum version is more likely to have a negative impact on the project’s efforts.
  • Another topic discussed was the safeguarding of such incompatible plugins and themes, when they are attempted to be used. A site owner should be prevented to interact with such an extension as early as possible, i.e. when installing it. If it is installed through a way that WordPress cannot control, such as uploading manually, then it should at least apply the same restriction on activation. A follow-up discussion to the meeting questioned whether this restriction should be enforced, or alternatively only suggested, for example by using indicative colors in the UI. 
  • In that regard, it needs to be ensured that the more experienced users are accounted for as well, in case they want to be informed of fatal errors in the more traditional way and get around the safeguarding mechanisms. An idea could be to provide a constant or otherwise configurable flag to disable the safeguarding mechanisms, which could cover both the extension restriction and the WSOD prevention. By default these should definitely be enabled, to account for the majority of users. This being configurable would allow to circumvent the hard restrictions, which are preferable for the common case.

Next week’s meeting

  • Next meeting will take place on Monday, November 26th, 2018 at 16:00 UTC in #core-php.
  • Agenda: Open floor.
  • If you have suggestions about this but cannot make the meeting, please leave a comment on this post so that we can take them into account.

#core-php, #php, #servehappy

PHP Meeting Recap – November 12th

This recap is a summary of our previous PHP meeting. It highlights the ideas and decisions which came up during that meeting, both as a means of documenting and to provide a quick overview for those who were unable to attend.

You can find this meeting’s chat log here.

Chat Summary

  • @schlessera adapted the README.md in the Servehappy repository so that it just links to the Feature Project page, to avoid requiring both to stay in sync.
  • Adding support for PHP version requirements to themes was discussed (Meta Trac #3718). The current state of the requirement for themes to have a readme.txt file does not seem to be clearly defined, as the only source of truth is the combination of an old blog post from 2015 and its collection of comments.
  • @afragen proposed to split the individual next actions for theme support into separate tickets, just as we did with plugins.
  • We also initiated contact with one of the team leads of the #themereview team (@williampatton) to discuss the current state of the theme’s readme.txt requirements.
  • @schlessera noted that while it seems we need to help move some unrelated stuff forward to get around our own blockers, we should be careful to avoid taking on too much responsibility and wasting our time on unrelated efforts.

Next week’s meeting

  • Next meeting will take place on Monday, November 19th, 2018 at 15:00 UTC in #core-php.
  • Agenda: Open floor.
  • If you have suggestions about this but cannot make the meeting, please leave a comment on this post so that we can take them into account.

#core-php, #php, #servehappy, #summary

PHP Meeting Recap – November 5th

This recap is a summary of our previous PHP meeting. It highlights the ideas and decisions which came up during that meeting, both as a means of documenting and to provide a quick overview for those who were unable to attend.

You can find this meeting’s chat log here.

Chat Summary

  • Note that, in order to maintain the original time in most parts of the world after the end of daylight saving time, the meeting time has been adjusted from 15:00 UTC to 16:00 UTC.
  • Due to the focus on Gutenberg and the resulting lack of activity in other areas, this and the following meetings should preferably be used for some “housekeeping”, reviewing the project roadmap and planning the next steps after 5.0.
  • @flixos90 asked to review the Servehappy feature project page, since that has not been updated in a long time. The page would later be updated to reflect some of the additional requirements that came up mid-2018 and to show the currently planned timelines for all features in the project’s scope, plus links to relevant resources and tickets.
  • @afragen brought up #44619 which had not been tagged with the “servehappy” keyword before, mentioning that the ticket is close to ready. @sergeybiryukov pointed out that it should receive design feedback first.
  • @joyously asked about the plans for themes requiring certain PHP versions. While nothing has been developed in this regard yet, themes should eventually be able to specify a minimum required PHP version, just like plugins. This information should be available through the Themes API, and WordPress core should implement techniques to restrict installation, updates and activation of such themes if the requirements are not met, again just how it has been worked on for plugins for the past couple months. However proceeding with this is currently blocked by the lack of theme readme support for wordpress.org, since the minimum requirements should be specified via the readme.
  • The Tide project could in the future be used as an additional means to determine PHP compatibility of plugins and themes.

Next week’s meeting

  • Next meeting will take place on Monday, November 12th, 2018 at 16:00 UTC in #core-php.
  • Agenda: Review future proceedings for the project and refine roadmap and priorities.
  • If you have suggestions about this but cannot make the meeting, please leave a comment on this post so that we can take them into account.

#core-php, #php, #servehappy