Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to PHP 8.2 #644

Open
sybrew opened this issue Aug 27, 2023 · 2 comments
Open

Upgrade to PHP 8.2 #644

sybrew opened this issue Aug 27, 2023 · 2 comments
Assignees
Milestone

Comments

@sybrew
Copy link
Owner

sybrew commented Aug 27, 2023

See #98 and #608.

We expect TSF v5.0 to be released late 2024-- that's when most sites have hopefully upgraded to a secure PHP version–that'd be 8.2. See https://www.php.net/supported-versions.php.

Since the jump from PHP 8.0 to 8.2 is perceived as minor, we expect that most PHP 8.X users will be on 8.2 by the time we upgrade from 7.4.

Features we'd want to utilize

PHP 8.0

  • Named arguments
    • Makes code much more readable.
  • Construction promotion
    • Instantly shows that construction arguments become class properties. This should improve readability and reduce code footprint.
    • However, I have never seen this used before (probably because PHP 8 isn't in widespread use), so I'm not sure if future coders will understand this.
  • Match expression
    • Condenses return-based/value-assigning switch-statements.
  • Nullsafe operator
    • Reduces the need for chaining with isset()/method_exists()/etc., condensing code.
  • str_contains()/str_starts_with()/str_ends_with()
    • Less false/0 !== strpos()/strrpos(), more readable code.

PHP 8.1

  • Named arguments after unpacking
    • Makes code a little more readable.
  • Fibers
    • This is interesting. We can utilize this for generation by suspending coroutines when one value is reached. However, this is quite challenging to make logical, and this feature is probably intended for remote requests.
  • array_is_list()
    • Condenses API functions that rely on lists, or allow both lists (sequential) and associative arrays.
  • Readonly properties
    • This will make me not have to mark everything "@Private".

PHP 8.2

  • Readonly classes
    • Same as readonly properties, but then simpler.
  • Constant in traits
    • Another good reason to start embracing traits and actual OOP.

Conclusion

The tiny list of features in 8.2 does not justify an upgrade unless we can reasonably assume most sites are upgraded.

Proposed version

Ref: https://wordpress.org/about/stats/

We'll upgrade to a version that at least 66% of sites support at our scheduled release. We previously aimed at 85%. However, since WordPress reports data from inactive sites and prevents users from updating plugins with unsupported required PHP versions, I see no issue in upgrading earlier.

TSF v5.0 will have an estimated 6-month development cycle. Hopefully, we can get started somewhere early or even before 2024.
Extension Manager's upgrade will follow soon after that.

@sybrew sybrew added this to the 5.0.0 milestone Aug 27, 2023
@sybrew sybrew self-assigned this Aug 27, 2023
@chesio
Copy link

chesio commented Aug 27, 2023

I also find enums (added in PHP 8.1) quite useful.

@sybrew
Copy link
Owner Author

sybrew commented Sep 25, 2023

I simulated the Fiber API here; it's where we could benefit by upgrading, where we need not test for also valid() and next() -- but only resume() (now current()) and isTerminated() (now false):

// Simulate the Fiber API. TODO PHP8.0+ make actual Fiber.
$memo['fiber'] ??= null;
$fiber = &$memo['fiber'];
if ( isset( $fiber ) ) {
// If Fiber's exhausted, go to next generator.
if ( ! $fiber ) continue;
// Iterate to next if still valid from last run.
$fiber->next();
} else {
$fiber = \call_user_func_array( $cb, [ null, $size ] );
}
// phpcs:ignore, WordPress.CodeAnalysis.AssignmentInCondition -- gotta check and end early.
while ( $fiber->valid() || ( $fiber = false ) ) {
$details = \tsf()->s_image_details( static::merge_extra_image_details(
$fiber->current(),
$size,
) );
if ( $details['url'] ) {
yield $memo['values'][] = $details;
if ( $single ) break 2;
}
$fiber->next();
}

We have various functions that could benefit from array_is_list():

// PHP 8.1+, use `!array_is_list()`?
// This is 350x faster than a polyfill for `!array_is_list()`.
if ( [] === $array || array_values( $array ) !== $array ) return $array;

This could be condensed using array unpacking by string (...dimensions,[ etc, ]):

// This returns an array with 'width' and 'height' indexes.
$details += Image\Utils::get_image_dimensions( $details['id'], $size );
// TODO PHP 8.1+ String unpacking in array, so we can directly add the above to it:
$details += [
'alt' => Image\Utils::get_image_alt_tag( $details['id'] ),
'caption' => Image\Utils::get_image_caption( $details['id'] ),
'filesize' => Image\Utils::get_image_filesize( $details['id'], $size ),
];

We're already using str_contains() and str_starts_with() because WordPress provides polyfills.

Some properties could benefit from being readonly -- for now, I marked those as "private" or blocked access altogether by requiring a functional interface. Bypassing the function overhead could speed things up and make the code more readable, especially since the nullsafe operator is also available.

About enums... this requires a new way of thinking about objects -- I'm not sure if it's backportable. I'll look into this one a bit more once we can actually embrace it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants