PHPackages                             symfony/polyfill - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. symfony/polyfill

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

symfony/polyfill
================

Symfony polyfills backporting features to lower PHP versions

v1.40.0(1mo ago)2.8k4.7M↓23.3%157[1 PRs](https://github.com/symfony/polyfill/pulls)20MITPHPPHP &gt;=7.2CI failing

Since Nov 4Pushed 6d ago35 watchersCompare

[ Source](https://github.com/symfony/polyfill)[ Packagist](https://packagist.org/packages/symfony/polyfill)[ Docs](https://symfony.com)[ Fund](https://symfony.com/sponsor)[ GitHub Sponsors](https://github.com/fabpot)[ RSS](/packages/symfony-polyfill/feed)WikiDiscussions 1.x Synced 3w ago

READMEChangelog (9)Dependencies (15)Versions (80)Used By (20)Security (2)

Symfony Polyfill
================

[](#symfony-polyfill)

This project backports features found in the latest PHP versions and provides compatibility layers for some extensions and functions. It is intended to be used when portability across PHP versions and extensions is desired.

Polyfills are provided for:

- the `apcu` extension when the legacy `apc` extension is installed;
- the `ctype` extension when PHP is compiled without ctype;
- the `deepclone` extension (`deepclone_to_array` and `deepclone_from_array` functions);
- the `mbstring` and `iconv` extensions;
- the `uuid` extension;
- the `MessageFormatter` class and the `msgfmt_format_message` functions;
- the `Normalizer` class and the `grapheme_*` functions;
- the `utf8_encode` and `utf8_decode` functions from the `xml` extension or PHP-7.2 core;
- the `Collator`, `NumberFormatter`, `Locale`, `IntlDateFormatter` and `IntlListFormatter` classes, limited to the "en" locale;
- the `intl_error_name`, `intl_get_error_code`, `intl_get_error_message` and `intl_is_failure` functions;
- the `idn_to_ascii` and `idn_to_utf8` functions;
- a `Binary` utility class to be used when compatibility with `mbstring.func_overload` is required;
- the `spl_object_id` and `stream_isatty` functions introduced in PHP 7.2;
- the `mb_ord`, `mb_chr` and `mb_scrub` functions introduced in PHP 7.2 from the `mbstring` extension
- the `sapi_windows_vt100_support` function (Windows only) introduced in PHP 7.2;
- the `PHP_FLOAT_*` constant introduced in PHP 7.2;
- the `PHP_OS_FAMILY` constant introduced in PHP 7.2;
- the `is_countable` function introduced in PHP 7.3;
- the `array_key_first` and `array_key_last` functions introduced in PHP 7.3;
- the `hrtime` function introduced in PHP 7.3;
- the `JsonException` class introduced in PHP 7.3;
- the `normalizer_get_raw_decomposition` function introduced in PHP 7.3;
- the `get_mangled_object_vars`, `mb_str_split` and `password_algos` functions introduced in PHP 7.4;
- the `fdiv` function introduced in PHP 8.0;
- the `get_debug_type` function introduced in PHP 8.0;
- the `preg_last_error_msg` function introduced in PHP 8.0;
- the `str_contains` function introduced in PHP 8.0;
- the `str_starts_with` and `str_ends_with` functions introduced in PHP 8.0;
- the `ValueError` class introduced in PHP 8.0;
- the `UnhandledMatchError` class introduced in PHP 8.0;
- the `FILTER_VALIDATE_BOOL` constant introduced in PHP 8.0;
- the `get_resource_id` function introduced in PHP 8.0;
- the `Attribute` class introduced in PHP 8.0;
- the `Stringable` interface introduced in PHP 8.0;
- the `PhpToken` class introduced in PHP 8.0 when the tokenizer extension is enabled;
- the `array_is_list` function introduced in PHP 8.1;
- the `enum_exists` function introduced in PHP 8.1;
- the `MYSQLI_REFRESH_REPLICA` constant introduced in PHP 8.1;
- the `ReturnTypeWillChange` attribute introduced in PHP 8.1;
- the `CURLStringFile` class introduced in PHP 8.1 (but only if PHP &gt;= 7.4 is used);
- the `CURLOPT_ISSUERCERT_BLOB` constant introduced in PHP 8.1 when curl 7.47+ is used;
- the `AllowDynamicProperties` attribute introduced in PHP 8.2;
- the `SensitiveParameter` attribute introduced in PHP 8.2;
- the `SensitiveParameterValue` class introduced in PHP 8.2;
- the `Random\Engine` interface introduced in PHP 8.2;
- the `Random\CryptoSafeEngine` interface introduced in PHP 8.2;
- the `Random\Engine\Secure` class introduced in PHP 8.2 (check [arokettu/random-polyfill](https://packagist.org/packages/arokettu/random-polyfill) for more engines);
- the `odbc_connection_string_is_quoted` function introduced in PHP 8.2;
- the `odbc_connection_string_should_quote` function introduced in PHP 8.2;
- the `odbc_connection_string_quote` function introduced in PHP 8.2;
- the `ini_parse_quantity` function introduced in PHP 8.2;
- the `CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256` constant introduced in PHP 8.1 when curl 7.50+ is used;
- the `json_validate` function introduced in PHP 8.3;
- the `Override` attribute introduced in PHP 8.3;
- the `mb_str_pad` function introduced in PHP 8.3;
- the `ldap_exop_sync` function introduced in PHP 8.3;
- the `ldap_connect_wallet` function introduced in PHP 8.3;
- the `stream_context_set_options` function introduced in PHP 8.3;
- the `str_increment` and `str_decrement` functions introduced in PHP 8.3;
- the `Date*Exception/Error` classes introduced in PHP 8.3;
- the `SQLite3Exception` class introduced in PHP 8.3;
- the `mb_ucfirst` and `mb_lcfirst` functions introduced in PHP 8.4;
- the `array_find`, `array_find_key`, `array_any` and `array_all` functions introduced in PHP 8.4;
- the `Deprecated` attribute introduced in PHP 8.4;
- the `mb_trim`, `mb_ltrim` and `mb_rtrim` functions introduced in PHP 8.4;
- the `ReflectionConstant` class introduced in PHP 8.4
- the `CURL_HTTP_VERSION_3` and `CURL_HTTP_VERSION_3ONLY` constants introduced in PHP 8.4;
- the `grapheme_str_split` function introduced in PHP 8.4;
- the `bcceil`, `bcdivmod`, `bcfloor` and `bcround` functions introduced in PHP 8.4;
- the `PDO` driver specific sub-classes introduced in PHP 8.4;
- the `get_error_handler` and `get_exception_handler` functions introduced in PHP 8.5;
- the `NoDiscard` attribute introduced in PHP 8.5;
- the `array_first` and `array_last` functions introduced in PHP 8.5;
- the `DelayedTargetValidation` attribute introduced in PHP 8.5;
- the `Filter\FilterException` class introduced in PHP 8.5;
- the `Filter\FilterFailedException` class introduced in PHP 8.5;
- the `grapheme_levenshtein` function introduced in PHP 8.5;
- the `locale_is_right_to_left` function introduced in PHP 8.5;
- the `clamp` function introduced in PHP 8.6;
- the `ARRAY_FILTER_USE_VALUE` constant introduced in PHP 8.6;
- the `SortDirection` enum introduced in PHP 8.6;
- the `grapheme_strrev` function introduced in PHP 8.6;
- the `Io\Poll` API and `StreamPollHandle` introduced in PHP 8.6 (requires PHP &gt;= 8.1; only the `Poll` backend is available);

It is strongly recommended to upgrade your PHP version and/or install the missing extensions whenever possible. This polyfill should be used only when there is no better choice or when portability is a requirement.

Design principles
=================

[](#design-principles)

Polyfills target the API of the latest PHP version and backport it to older ones. The goal is that code written for a recent PHP runs unchanged on the oldest supported version; it is not to reproduce the historical behavior of every intermediate version. In practice:

- New functions, classes, constants and arguments are backported; removed or legacy behavior is not. For example, the `is_hex` argument that `mb_decode_numericentity()` lost in PHP 8.0 is not accepted by the polyfill.
- A symbol is backported only when defining it carries the native effect. A constant whose sole purpose is to switch on behavior in a function that cannot be polyfilled is left undefined, so its absence stays usable for feature detection, e.g. `FILTER_THROW_ON_FAILURE`, which only configures `filter_var()`. Declarative symbols such as attributes are polyfilled even when their runtime effect needs engine support, since reflection still conveys their semantics.
- A polyfill runs only when the native symbol is missing, so it reproduces the contract of the function it shims rather than a blanket "PHP 7" or "PHP 8" behavior. Functions that always raised a `ValueError` on invalid input throw on every supported version (a `ValueError` stub is declared on PHP &lt; 8 where needed); functions whose native contract returned `false` keep returning `false`.
- The signatures declared by the bootstrap files match the native signature of the PHP version being run, so the polyfill stays a drop-in that the engine can supersede. New arguments that cannot be implemented are accepted and ignored, e.g. the `$locale` argument added to the `grapheme_*()` functions in PHP 8.5.
- Extensions that were never bundled with PHP, such as `uuid` and `deepclone`, follow the extension's own release history rather than PHP's. Since a polyfill cannot influence `extension_loaded()` nor conditionally define constants, it mirrors the newest native state, including deprecations: `UUID_TYPE_DCE` and `UUID_TYPE_NAME` are defined with a `Deprecated` attribute on PHP 8.5+.
- When a function is provided by both an extension polyfill (`Mbstring`) and a version polyfill (`Php74`, `Php83`, `Php84`), both implementations must behave identically, because either one may end up registered depending on the PHP version and whether the extension is loaded.

Compatibility notes
===================

[](#compatibility-notes)

To write portable code between PHP5 and PHP7, some care must be taken:

- `\*Error` exceptions must be caught before `\Exception`;
- after calling `error_clear_last()`, the result of `$e = error_get_last()` must be verified using `isset($e['message'][0])` instead of `null !== $e`.

Usage
=====

[](#usage)

When using [Composer](https://getcomposer.org/) to manage your dependencies, you should **not** `require` the `symfony/polyfill` package, but the standalone ones:

- `symfony/polyfill-apcu` for using the `apcu_*` functions,
- `symfony/polyfill-ctype` for using the ctype functions,
- `symfony/polyfill-deepclone` for using the `deepclone_*` functions,
- `symfony/polyfill-php54` for using the PHP 5.4 functions,
- `symfony/polyfill-php55` for using the PHP 5.5 functions,
- `symfony/polyfill-php56` for using the PHP 5.6 functions,
- `symfony/polyfill-php70` for using the PHP 7.0 functions,
- `symfony/polyfill-php71` for using the PHP 7.1 functions,
- `symfony/polyfill-php72` for using the PHP 7.2 functions,
- `symfony/polyfill-php73` for using the PHP 7.3 functions,
- `symfony/polyfill-php74` for using the PHP 7.4 functions,
- `symfony/polyfill-php80` for using the PHP 8.0 functions,
- `symfony/polyfill-php81` for using the PHP 8.1 functions,
- `symfony/polyfill-php82` for using the PHP 8.2 functions,
- `symfony/polyfill-php83` for using the PHP 8.3 functions,
- `symfony/polyfill-php84` for using the PHP 8.4 functions,
- `symfony/polyfill-php85` for using the PHP 8.5 functions,
- `symfony/polyfill-iconv` for using the iconv functions,
- `symfony/polyfill-intl-grapheme` for using the `grapheme_*` functions,
- `symfony/polyfill-intl-idn` for using the `idn_to_ascii` and `idn_to_utf8` functions,
- `symfony/polyfill-intl-icu` for using the intl functions and classes,
- `symfony/polyfill-intl-messageformatter` for using the intl messageformatter,
- `symfony/polyfill-intl-normalizer` for using the intl normalizer,
- `symfony/polyfill-io-poll` for using the `Io\Poll` API and `StreamPollHandle`,
- `symfony/polyfill-mbstring` for using the mbstring functions,
- `symfony/polyfill-util` for using the polyfill utility helpers.
- `symfony/polyfill-uuid` for using the `uuid_*` functions,

Requiring `symfony/polyfill` directly would prevent Composer from sharing correctly polyfills in dependency graphs. As such, it would likely install more code than required.

Design
======

[](#design)

This package is designed for low overhead and high quality polyfilling.

It adds only a few lightweight `require` statements to the bootstrap process to support all polyfills. Implementations are then loaded on-demand when needed during code execution.

If your project requires a minimum PHP version it is advisable to add polyfills for lower PHP versions to the `replace` section of your `composer.json`. This removes any overhead from these polyfills as they are no longer part of your project. The same can be done for polyfills for extensions that you require.

If your project requires php 7.0, and needs the mb extension, the replace section would look something like this:

```
{
    "replace": {
        "symfony/polyfill-php54": "*",
        "symfony/polyfill-php55": "*",
        "symfony/polyfill-php56": "*",
        "symfony/polyfill-php70": "*",
        "symfony/polyfill-mbstring": "*"
    }
}
```

Polyfills are unit-tested alongside their native implementation so that feature and behavior parity can be proven and enforced in the long run.

License
=======

[](#license)

This library is released under the [MIT license](LICENSE).

###  Health Score

74

—

ExcellentBetter than 100% of packages

Maintenance95

Actively maintained with recent releases

Popularity70

Solid adoption and visibility

Community46

Growing community involvement

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 60.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~76 days

Recently: every ~8 days

Total

52

Last Release

24d ago

PHP version history (3 changes)v1.0.0PHP &gt;=5.3.3

v1.20.0PHP &gt;=7.1

v1.31.0PHP &gt;=7.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/47313?v=4)[Fabien Potencier](/maintainers/fabpot)[@fabpot](https://github.com/fabpot)

---

Top Contributors

[![nicolas-grekas](https://avatars.githubusercontent.com/u/243674?v=4)](https://github.com/nicolas-grekas "nicolas-grekas (575 commits)")[![fabpot](https://avatars.githubusercontent.com/u/47313?v=4)](https://github.com/fabpot "fabpot (127 commits)")[![derrabus](https://avatars.githubusercontent.com/u/1506493?v=4)](https://github.com/derrabus "derrabus (27 commits)")[![xabbuh](https://avatars.githubusercontent.com/u/1957048?v=4)](https://github.com/xabbuh "xabbuh (21 commits)")[![Ayesh](https://avatars.githubusercontent.com/u/811553?v=4)](https://github.com/Ayesh "Ayesh (19 commits)")[![stof](https://avatars.githubusercontent.com/u/439401?v=4)](https://github.com/stof "stof (19 commits)")[![IonBazan](https://avatars.githubusercontent.com/u/1985514?v=4)](https://github.com/IonBazan "IonBazan (17 commits)")[![BackEndTea](https://avatars.githubusercontent.com/u/14289961?v=4)](https://github.com/BackEndTea "BackEndTea (15 commits)")[![webmozart](https://avatars.githubusercontent.com/u/176399?v=4)](https://github.com/webmozart "webmozart (13 commits)")[![keradus](https://avatars.githubusercontent.com/u/2716794?v=4)](https://github.com/keradus "keradus (13 commits)")[![GPHemsley](https://avatars.githubusercontent.com/u/376064?v=4)](https://github.com/GPHemsley "GPHemsley (12 commits)")[![jakzal](https://avatars.githubusercontent.com/u/190447?v=4)](https://github.com/jakzal "jakzal (9 commits)")[![jderusse](https://avatars.githubusercontent.com/u/578547?v=4)](https://github.com/jderusse "jderusse (8 commits)")[![GrahamCampbell](https://avatars.githubusercontent.com/u/2829600?v=4)](https://github.com/GrahamCampbell "GrahamCampbell (6 commits)")[![lyrixx](https://avatars.githubusercontent.com/u/408368?v=4)](https://github.com/lyrixx "lyrixx (5 commits)")[![TRowbotham](https://avatars.githubusercontent.com/u/4984601?v=4)](https://github.com/TRowbotham "TRowbotham (5 commits)")[![TimWolla](https://avatars.githubusercontent.com/u/209270?v=4)](https://github.com/TimWolla "TimWolla (5 commits)")[![Tobion](https://avatars.githubusercontent.com/u/610090?v=4)](https://github.com/Tobion "Tobion (5 commits)")[![TysonAndre](https://avatars.githubusercontent.com/u/1904430?v=4)](https://github.com/TysonAndre "TysonAndre (4 commits)")[![gharlan](https://avatars.githubusercontent.com/u/330436?v=4)](https://github.com/gharlan "gharlan (4 commits)")

---

Tags

componentphppolyfillportabilitysymfonysymfony-componentcompatibilitypolyfillshimdevcompat

### Embed Badge

![Health badge](/badges/symfony-polyfill/health.svg)

```
[![Health](https://phpackages.com/badges/symfony-polyfill/health.svg)](https://phpackages.com/packages/symfony-polyfill)
```

###  Alternatives

[symfony/polyfill-mbstring

Symfony polyfill for the Mbstring extension

7.8k1.2B777](/packages/symfony-polyfill-mbstring)[symfony/polyfill-php72

Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions

4.7k688.6M35](/packages/symfony-polyfill-php72)[symfony/polyfill-util

Symfony utilities for portability of PHP codes

1.3k124.5M7](/packages/symfony-polyfill-util)[symfony/polyfill-intl-idn

Symfony polyfill for intl's idn\_to\_ascii and idn\_to\_utf8 functions

3.4k823.1M148](/packages/symfony-polyfill-intl-idn)[symfony/polyfill-intl-normalizer

Symfony polyfill for intl's Normalizer class and related functions

2.1k885.3M66](/packages/symfony-polyfill-intl-normalizer)[symfony/polyfill-php73

Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions

2.4k602.0M85](/packages/symfony-polyfill-php73)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
