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()
andrandom_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, - 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, - symfony/polyfill-intl-grapheme for using the
grapheme_*()
functions, - symfony/polyfill-intl-icu for using the
intl
functions and classes, - symfony/polyfill-intl-normalizer for using the
intl
normalizer, - symfony/polyfill-mbstring for using the
mbstring
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.
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.
This is probably the best feature for 2.8! No more worries which php version your function may or may not support when contributing.
I love this as well, great pick up!