March 10, 2016 Javier Eguiluz

In web development, a polyfill is "additional code which provides facilities that are not built into a web browser". They are wildly popular in JavaScript applications because they provide a uniform API regardless of the features provided by users' browsers.

This was the very same issue that Symfony was increasingly facing as more diverse PHP versions were being supported, from the ancient PHP 5.3.3 (released on July 2010!) to the cutting-edge PHP 7.0. The differences in those PHP versions made us include lots of PHP version comparisons:

1 2 3 4 5 if ( PHP_VERSION_ID >= 50400 ) { session_register_shutdown (); } else { register_shutdown_function ( 'session_write_close' ); }

We also needed to perform a lot of function checks because some important PHP extensions may be missing when executing Symfony applications:

1 2 3 4 5 6 7 if ( function_exists ( 'mb_strlen' )) { $params [ $index ] = mb_substr ( ... ); } else { $params [ $index ] = substr ( ... ); } // ...

Introducing PHP Polyfills¶ Supporting five different PHP branches across the entire Symfony codebase was becoming a maintenance hell. For that reason, we decided to create several small polyfill components to "fill the gaps" of PHP 5.x versions and missing extensions. For example, to use some of the great new PHP functions provided by PHP 7.0 in any PHP 5.x application, you just need to install the symfony/polyfill-php70 component: 1 $ composer require symfony/polyfill-php70 Now your project can start using these functions included natively in PHP 7 and provided via PHP 5.x code by this component: intdiv()

preg_replace_callback_array()

error_clear_last()

random_bytes() and random_int() This PHP 7 polyfill also provides the *Error throwable classes.

Pick your PHP polyfill¶ Symfony project has already published 12 decoupled polyfill components, which can be used separately in your applications: symfony/polyfill-apcu for using the apcu_*() functions,

functions, symfony/polyfill-php54 for using the new functions introduced by PHP 5.4,

symfony/polyfill-php55 for using the new functions introduced by PHP 5.5,

symfony/polyfill-php56 for using the new functions introduced by PHP 5.6,

symfony/polyfill-php70 for using the new functions introduced by PHP 7.0,

symfony/polyfill-iconv for using the iconv functions,

functions, symfony/polyfill-intl-grapheme for using the grapheme_*() functions,

functions, symfony/polyfill-intl-icu for using the intl functions and classes,

functions and classes, symfony/polyfill-intl-normalizer for using the intl normalizer,

normalizer, symfony/polyfill-mbstring for using the mbstring functions,

functions, symfony/polyfill-util for using the polyfill utility helpers,

symfony/polyfill-xml for using the utf8_encode()/decode() functions. As you can see in this pull request, using all these polyfills allowed Symfony 2.8 to remove around 800 lines of code.