Slide 1

Slide 1 text

Getting Ready for PHP 8.0 Juliette Reinders Folmer Tweet about it: @jrf_nl Justin Visser

Slide 2

Slide 2 text

PHP 8 26 November 2020 © FlyClipArt

Slide 3

Slide 3 text

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"

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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*

Slide 6

Slide 6 text

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*

Slide 7

Slide 7 text

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*

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

▪ (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- (or 7.4-) Psalm PHPStan PHPCompatibilityWP Running Scans WP

Slide 10

Slide 10 text

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*

Slide 11

Slide 11 text

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*

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Reserved Keywords ▪ New Reserved Keyword(s): - match - enum (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;

Slide 14

Slide 14 text

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()

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

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 ) {}

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

TypeErrors for PHP Native Functions

Slide 23

Slide 23 text

Resource to Object Migrations ▪ GD, GDImage is_gd_image() ▪ Curl ▪ OpenSSL ▪ Sockets ▪ XML ▪ XMLWriter ▪ ZIP if (is_resource($r)) { if ($r !== false) { // Do something. }

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

An Example

Slide 26

Slide 26 text

Another example

Slide 27

Slide 27 text

test Test TEST

Slide 28

Slide 28 text

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*

Slide 29

Slide 29 text

How to Fix TypeErrors ? Truly analyse the code and apply defensive coding Cast to type try { … } catch( TypeError $e ) { … } Don't fix.

Slide 30

Slide 30 text

For public/OS code: ❑ 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 add it, add some more tests Example: https://core.trac.wordpress.org/ticket/52534 BEWARE OF BC BREAKS

Slide 31

Slide 31 text

Open Invite Every other Friday ~ 13:00 UTC

Slide 32

Slide 32 text

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);

Slide 33

Slide 33 text

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*

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

What about WordPress Core ?

Slide 36

Slide 36 text

“ 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"

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

"beta-compatible" Fix all KNOWN issues based on tests Fix all issues based on scans New PHP 8 issues being reported every week Undiscovered issues ? Parameter name review Plugins & themes not being compatible Plugins & themes doing it wrong™

Slide 39

Slide 39 text

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/

Slide 40

Slide 40 text

Thanks! Any questions ? Slides: https://speakerdeck.com/jrf @jrf_nl @jrfnl