Nicolas Grekas
Contributed by Nicolas Grekas in #16240 and #16317

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:

As you can see in this pull request, using all these polyfills allowed Symfony 2.8 to remove around 800 lines of code.

The next PHP polyfills

If you think that some other polyfill might be useful for Symfony or PHP in general, open an issue in the main symfony/polyfill repository and ask for it. You can also propose your own polyfill code, as long as it meets the Symfony quality standard and provides behavior parity with the native version.

Published in #Living on the edge