Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting Ready for PHP 8.0

Getting Ready for PHP 8.0

Presented on April 22nd 2021 for employees of Yoast (closed DevTalk meeting).

Juliette Reinders Folmer

April 22, 2021
Tweet

More Decks by Juliette Reinders Folmer

Other Decks in Programming

Transcript

  1. New in PHP 8.0 Match control structure Attributes Nullsafe object

    operator Trailing comma in closure use Constructor property promotion Non capturing catch Union types Mixed type Static return type Throw expressions Stringable Magic method signature check Stable sorting ::class on objects Syntax tweaks Named arguments Reclassify engine warnings Saner numeric strings Saner string to number comparisons Locale independent float to string cast Stricter type check for arithmetic/ bitwise operators Consistent type errors for internal functions "bug fixes"
  2. Timeline Aug Sep Oct Nov 8.0.0 Dec Jan 8.0.2 Feb

    Mar 8.0.4 Apr May 8.0.6 Jun Jul 8.0.8 Production Apps Open Source Apps QA & tools
  3. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  4. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  5. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  6. Scan vs Test Results depend on Tool Capabilities & Readiness

    Unit Tests Integration Tests E2E Tests Acceptance Tests …. Results depend on Test Suite Completeness PHPCompatibility PHPStan Psalm Exakat
  7. ▪ (low = more) ▪ Level 5, exclude level 0-4

    (low = less) ▪ Use v 10.0.0 / develop with recent PHP_CodeSniffer ▪ Run with --runtime-set testVersion 5.6- Psalm PHPStan PHPCompatibilityWP Running Scans WP
  8. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  9. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  10. Removed/Permanently changed (previously deprecated) Curly brace array/string dereferencing Deprecated ini

    directives, functions and function arguments mb_ereg_replace e modifier Concatenation operator precedence (real) (unset) Nested ternaries without parentheses Calling non- static methods statically PHP 4 class constructors
  11. Reserved Keywords ▪ New Reserved Keyword(s): - match - ~

    mixed - enum (PHP 8.1) - never (PHP 8.1) ▪ Reserved keywords can now be used in namespace names ▪ Trade off: white space no longer allowed in namespaced names namespace My\Global\Classes; use My\VeryLong\VeryLong\ NamespaceName\ClassName;
  12. Error Handling ▪ @ no longer silences fatal errors ▪

    Default error level E_ALL (previously excluded E_NOTICE and E_DEPRECATED) ▪ display_startup_errors enabled by default ▪ $php_errormsgno longer available ▪ Custom error handlers will no longer receive $errcontext ▪ Uncaught Exceptions will go through "clean shutdown" ▪ exit() in __construct() will no longer call __destruct()
  13. Error Level Changes Warning -> Error ▪ Writing to a

    property of non- object ▪ Assign to array with key > PHP_INT_MAX ▪ Invalid array key type ▪ Invalid string offset type ▪ Write to array index on scalar ▪ Unpack non-array/Traversable ▪ Access to undefined constants Notice -> Warning ▪ Read undefined variable ▪ Read undefined property ▪ Read undefined array key ▪ Read property of non-object ▪ Array access on non-array ▪ Array to string conversion ▪ Using resource as array key ▪ Using null, bool, float as string offset ▪ Read out-of-bounds string offset ▪ Assign empty string to string offset
  14. New Errors spl_autoload_register will throw TypeError XML-RPC moved to PECL

    Incompatible overloaded method signatures (LSP) Abstract trait method signature validation Invalid signatures for magic methods final private Reflection export() parent:: without parent class
  15. New Deprecations in PHP 8 Passing null to non- nullable

    PHP native functions (8.1) Various functions and methods Optional parameters before required Sorting callbacks returning boolean
  16. Changes in Handling of Numbers [1] Comparison | PHP <

    8 | PHP 8+ -------------------------------- 0 == "0" | true | true 0 == "0.0" | true | true 0 == "foo" | true | false 0 == "" | true | false 42 == " 42" | true | true 42 == "42foo" | true | false if ( $foo == $bar ) {}
  17. Changes in Handling of Numbers [2] function foo(int $i) {

    var_dump($i); } foo("123"); // int(123) foo(" 123"); // int(123) foo("123 "); // int(123) - PHP < 8: E_NOTICE, PHP 8+: no notice foo("123abc"); // int(123) - PHP < 8: E_NOTICE, PHP 8+: TypeError foo("string"); // TypeError $a = 123 + "123"; // int(246) $a = 123 + " 123"; $a = 123 + "123 "; // PHP < 8: E_NOTICE, PHP 8+: no notice $a = 123 + "123abc"; // PHP < 8: E_NOTICE, PHP 8+: E_WARNING $a = 123 + "string"; // int(123) - PHP < 8: E_WARNING, // PHP 8+: TypeError
  18. Changes in Handling of Numbers [3] $f = 3.14; Comparison

    | en_US | de_DE | PHP 8.0 --------------------------------------- (string) $f | 3.14 | 3,14 | 3.14 strval($f) | 3.14 | 3,14 | 3.14 print_r($f) | 3.14 | 3,14 | 3.14 implode([$f]) | 3.14 | 3,14 | 3.14
  19. Resource to Object Migrations ▪ GD, GDImage is_gd_image() ▪ Curl

    ▪ OpenSSL ▪ Sockets ▪ XML ▪ XMLWriter ▪ ZIP if (is_resource($r)) { if ($r !== false) { // Do something. }
  20. Other changes in Function Parameter or Return Types substr() et

    al vprintf() et al get_class_vars() filter_input() strtr() decbin() decoct() dechex() sem_get() datefmt_create() mb_decode_numericentity() mb_ereg[i]() pg_fetch_all() quote_meta() various enchant functions parse_url() * … and more
  21. An Example <?php declare(strict_types = 1); vprintf( 'The %s', 'dog'

    ); vprintf( 'The %s', ['dog'] ); PHP < 8.0 PHP 8.0 The dog Uncaught TypeError: vprintf(): The dog Argument #2 ($values) must be of type array, string given
  22. An Example <?php declare(strict_types = 1); vprintf( 'The %s', 'dog'

    ); vprintf( 'The %s', ['dog'] ); PHP < 8.0 PHP 8.0 The dog Uncaught TypeError: vprintf(): The dog Argument #2 ($values) must be of type array, string given
  23. Another example <?php $sub = substr('abcdef', 4, -4); if ($sub

    === false) { echo 'fail'; } else { echo 'do something with $sub'; } PHP < 8.0 PHP 8.0 fail do something with $sub
  24. Another example <?php $sub = substr('abcdef', 4, -4); if ($sub

    === false) { echo 'fail'; } else { echo 'do something with $sub'; } PHP < 8.0 PHP 8.0 fail do something with $sub
  25. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  26. How to Fix TypeErrors ? Truly analyse the code and

    apply defensive coding Cast to type try { … } catch( TypeError $e ) { … } Don't fix.
  27. Steps ❑ Isolate the problem ❑ Write tests before attempting

    a fix Make sure the tests include other unhappy paths! ❑ Create the fix ❑ [Optional, but recommended] While you're at it, add some more tests Example: https://core.trac.wordpress.org/ticket/52534 BEWARE OF BC BREAKS
  28. Named Parameters Any parameter name change is now a breaking

    change ❑ Review all parameter names for all non-private functions Recommended: don't use reserved keywords for parameter names ❑ Ensure parameters in overloaded methods are in sync with the parameter name in the parent class ❑ Review all calls to call_user_func_array() Open WordPress Core ticket: https://core.trac.wordpress.org/ticket/51553 function foo( $bar, $options = [], $strict = false ) {} foo(bar: $value); foo($value, strict: true);
  29. Getting Ready for a New PHP Version Compatible Dev Dependencies

    • Composer • Test Tools • Static Analysis Tools • Xdebug • PHP Scoper Compatible Runtime Dependencies Learn, Scan, Test & Fix Start Using New Features*
  30. New in PHP 8.0 Match control structure Attributes Nullsafe object

    operator Trailing comma in closure use Constructor property promotion Non capturing catch Union types Mixed type Static return type Throw expressions Stringable Stable sorting ::class on objects Syntax tweaks Named arguments
  31. “ For well-typed codebases or codebases which have stayed up-to-

    date with the latest PHP versions, there isn’t a big problem. The reality, however, is that WordPress is not such a codebase. "The 2020 WordPress and PHP Compatibility Report"
  32. Biggest Issues * Insufficient Tests AJAX calls hiding problems Filters,

    filters and more filters * Both for WordPress Core as well as for plugins and themes https://core.trac.wordpress.org/ticket/51525
  33. "beta-compatible" Fix all KNOWN issues based on tests Fix all

    issues based on scans New PHP 8 issues being reported every other week Undiscovered issues ? Parameter name review Plugins & themes not being compatible Plugins & themes doing it wrong™
  34. Further Reading ▪ PHP Manual: PHP 8.0 Migration Guide https://www.php.net/manual/en/migration80.php

    ▪ PHP 8.0 Changelog https://github.com/php/php-src/blob/PHP-8.0/UPGRADING ▪ The 2020 WordPress and PHP 8 Compatibility Report https://developer.yoast.com/blog/the-2020-wordpress-and-php-8- compatibility-report/ ▪ A Perfect Storm https://24daysindecember.net/2020/12/21/a-perfect-storm/ ▪ Type Declarations with WordPress Filters https://peterwilson.cc/type-declarations-with-wordpress-filters/ ▪ Open Sourcery Interview https://jonathanbossenger.com/podcast/open-sourcery-episode-1-juliette- reinders-folmer/