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

For the love of code: Modernizing WordPress, plugins, and themes

For the love of code: Modernizing WordPress, plugins, and themes

Presented on June 21st 2019 at WordCamp Europe, Berlin, Germany.
https://2019.europe.wordcamp.org/
---------------------------------------------------------------
Now that WordPress has committed to a minimum requirement of PHP 7 by the end of 2019, we can all start looking at modernizing the code we maintain. Removing hacks to support old versions is easy, but how can code be improved when it just works on PHP 7? Namespaces, generators, Intl are just a few of the features introduced since PHP 5.2, not to mention scalar type declarations and all the other awesomeness that came with PHP 7. But what does it all mean, and how can you take advantage of these goodies? Join Juliette to learn to identify where to make quick fixes, when to look into refactoring, and how to make your code faster, better and more secure by using modern PHP.

Juliette Reinders Folmer

June 21, 2019
Tweet

More Decks by Juliette Reinders Folmer

Other Decks in Programming

Transcript

  1. For the Love of Code: Modernizing WordPress, plugins and themes

    Juliette Reinders Folmer Tweet about it: @jrf_nl #ForTheLoveOfCode #WCEU
  2. WordPress versus PHP 4.2 4.3 4.4 5.0 5.1 5.2 5.3

    5.4 5.5 5.6 7.0 7.1 7.2 7.3 7.4 WP 2.0 Dec 2005 WP 2.5 Mar 2008 WP 3.2 July 2011 5.2.4 ... WP 5.2 May 2019 5.6.20 WP 5.? Dec 2019
  3. The fact that code runs on PHP 5.6+, does not

    make it PHP 5.6+ code BryanHanson
  4. What Needs to be Done ? Fix Incompati- bilities Use

    What Can Already be Used Clean Up Modernize Implement Quick Fixes Selectively Refactor
  5. Fix Existing Incompatibilities  PHP -l (lint)  PHPCompatibility 

    phan  php7cc  php7mar  php-compat-info Seemann
  6. Use What Can Already be Used PHP Native features like:

     Autoloading  Exceptions with try/catch  instanceof  Filter  SPL (Stnd PHP Library)  mysqli or PDO  Class name based type declarations  Array type declarations WP Polyfilled features like:  Sodium  CSPRNG (random_bytes(), random_int())  Various MbString functions  hash_equals()  JsonSerializable interface  spl_autoload_register()  array_replace_recursive()  is_iterable()  is_countable()
  7. Remove Hacks and Polyfills  version_compare()  extension_loaded()  class_exists()

     method_exist()  function_exists()  defined()  phpversion()  class_alias()  PHP_VERSION_ID  PHP_MAJOR_VERSION  PHP_MINOR_VERSION Lilla Frerichs
  8. Look Behind: Code for the now, but allow for the

    past Look Forward: Code for the lowest common denominator and allow for the future.
  9. Looking Forward vs Looking Behind if ( version_compare( phpversion(), '7.0',

    '>' ) ) { // Modern code. } // Old code. if ( version_compare( PHP_VERSION_ID, '59999', '<=' ) ) { // Back-fill for missing feature. Remove when ... } // More modern code.
  10. Use PHPUnit 5.4+ // Works with PHPUnit 3/4/5. class MyTest

    extends PHPUnit_Framework_TestCase { } // Works with PHPUnit 5.4/6/7. use PHPUnit\Framework\TestCase; class MyTest extends TestCase { } v Compatible with: 8 PHP 7.2, 7.3, 7.4 (support ends Feb 2021) 7 PHP 7.1, 7.2, 7.3 (support ends Feb 2020) 6 PHP 7.0, 7.1, 7.2 5 PHP 5.6, 7.0, 7.1 4 PHP 5.3, 5.4, 5.5, 5.6
  11. Use Composer { "name": "organization/my-plugin", "description": "A plugin...", "keywords": ["wordpress"],

    "license": "GPL-2.0-or-later", "type": "wordpress-plugin", "require": { "php": "^5.6.20 || ^7.0", }, "require-dev": { "humbug/php-scoper": "^0.6.0" }, "autoload": { "classmap": [ "src/" ] } }  ... but prevent dependency conflicts
  12. Best Practices  Focus on function, not syntax  Test

    Driven Refactoring GaborfromHungary
  13. Test Driven Refactoring Are there tests ? Do the tests

    actually cover the code ? Are the tests not just testing the "happy path" ?
  14. Best Practices  Focus on function, not syntax  Test

    Driven Refactoring  Don't attempt to do everything at once GaborfromHungary
  15. Best Practices  Focus on function, not syntax  Test

    Driven Refactoring  Don't attempt to do everything at once  Use the tools available GaborfromHungary
  16. Spread Operator Iterators & Generators Traits Namespaces Constant Scalar Expressions

    Quick Fixes Short Ternary & Null coalesce Type Declarations 5.3 5.4 5.6 5.3, 7.0, 7.4 5.0, 5.4, 7.0 – 7.2 5.6 5.2 - 5.5 5.3 - 7.4
  17. Before You Start  Think  Autoloading ? - PSR-0

    (deprecated) - PSR-4 - Custom - Classmap ngrigor
  18. What Do Namespaces Apply to ?  Functions  Classes

     Traits  Interfaces  Constants declared with const keyword  Variables  Constants declared with define()  Non-PHP native constructs: - hook names
  19. How Does it Work ? Namespace always applied • Classes

    • Traits • Interfaces Fallback to global namespace • Functions • Constants Namespace irrelevant • Magic Constants
  20. How Does it Work ? Namespace always applied • Classes

    • Traits • Interfaces Fallback to global namespace • Functions • Constants Namespace irrelevant • Magic Constants Must use FQN or use statement May use FQN or use statement N/A
  21. Namespaces class NSExample extends Base_Example { public function do_something( $input

    ) { return str_pad( $input, 10, '-', STR_PAD_LEFT ); } } $ns_example = new NSExample();
  22. Namespaces namespace MyNS; class NSExample extends Base_Example { public function

    do_something( $input ) { return str_pad( $input, 10, '-', STR_PAD_LEFT ); } } $ns_example = new NSExample();
  23. Namespaces namespace MyNS; class NSExample extends \Base_Example { public function

    do_something( $input ) { return \str_pad( $input, 10, '-', \STR_PAD_LEFT ); } } $ns_example = new NSExample();
  24. Import Use Statements namespace MyNS; use Base\Example; use function str_pad;

    use const STR_PAD_LEFT; class NSExample extends Example { public function do_something( $input ) { return str_pad( $input, 10, '-', STR_PAD_LEFT ); } } $ns_example = new NSExample(); 5.3 5.6
  25. PHP 7 Opcode Cached Functions  is_null()  is_bool() 

    is_long()  is_int()  is_integer()  is_float()  is_real()  is_string()  is_array()  is_object()  is_resource()  assert()  strlen()  defined()  call_user_func()  call_user_func_array()  boolval()  intval()  floatval()  doubleval()  strval()  chr()  ord()  in_array()  count()  get_class()  get_called_class()  gettype()  func_num_args()  func_get_args()  array_slice()  sizeof()  array_key_exists() 7.2 7.1 7.4 7.0
  26. Type Declarations  5.0: Parameter Type Declarations  7.0: Return

    Type Declarations  7.0: Strict Types  7.1: Nullable Types 5.0 Class/Interface name based 5.1 array 5.2 self parent 5.4 callable 7.0 bool, int, float, string 7.1 iterable, void 7.2 object
  27. Type Declarations function get_tax_posts( $taxonomies = null, $limit = 5)

    { _deprecated_function( __FUNCTION__, '5.x', 'wp_get_tax_posts' ); $taxonomies = (array) $taxonomies; $limit = (int) $limit; ... return $post_data; } function wp_get_tax_posts( ?array $taxonomies = null, int $limit = 5) : array { ... return $post_data; } return wp_get_tax_posts( $taxonomies, $limit );
  28. But.... There is so Much More ! Finally Garbage Collector

    Nested Exceptions Closures Goto Late Static Binding OpCache Nowdocs
  29. And Then There's PHP 7.... Expectations with assert() Unicode Escapes

    Group Use Declarations More Exception Types More Catchable Errors Uniform Variable Syntax Null Coalesce (equals) Scalar Type Hints & Return Type Hints
  30. And Yet More 7.x Goodies! Spread in arrays Multi catch

    Parameter type widening Short lists, keyed lists iterable, object & void types Nullable types Exceptions on Fatals Class constant visibility