symfony/polyfill-php85
Symfony Polyfill for PHP 8.5: backports upcoming core features for older PHP versions, including get_error_handler/get_exception_handler, NoDiscard, array_first/array_last, and the DelayedTargetValidation attribute.
Start by installing the package via Composer if you’re developing on PHP < 8.5 and need access to newer 8.5+ functions:
composer require symfony/polyfill-php85
No configuration is required—autoloading is handled automatically via Composer’s classmap. The first use case is typically leveraging array_first() and array_last() in legacy projects targeting PHP 7.4 or 8.0:
// Works on PHP < 8.5, thanks to the polyfill
$first = array_first($items, fn($item) => $item->isActive());
$last = array_last($items, fn($item) => $item->isPending());
Check the RFC pages and Polyfill README for full lists and caveats.
Backporting Future APIs: Use array_first()/array_last() to eliminate manual reset()/end() logic or array_filter() + array_slice() boilerplate, especially in data transformation pipelines.
Runtime Handler introspection: In logging or error-handling middleware, use get_error_handler() and get_exception_handler() to inspect or temporarily wrap handlers—only available on PHP 8.5+ or with the polyfill:
$originalHandler = get_exception_handler();
set_exception_handler(function ($e) use ($originalHandler) {
// custom logging...
return $originalHandler ? $originalHandler($e) : false;
});
NoDiscard compliance: Though the RFC affects return type declarations (e.g., #[NoDiscard]), the polyfill does not enforce or emulate attribute semantics at runtime—it only defines the attribute class for autoloading. Use it for documentation/IDE hints in PHP 8.0+ codebases, confident it won’t break on older versions due to autoloading safety.
DelayedTargetValidation: Define the attribute (it’s just a marker class in the polyfill), useful if you’re writing validation libraries that parse attributes at runtime and want forward compatibility.
No runtime enforcement: The polyfill only provides functions/classes—it doesn’t emulate RFC-level language behavior. For example, NoDiscard attributes remain inert unless your own code (e.g., custom static analysis tooling) interprets them.
PHP 8.5+ core inclusion: Starting with PHP 8.5, these functions and attributes are part of core. The polyfill automatically delegates to native implementations if available (since v1.28+), so there’s no performance penalty on modern PHP.
Namespace collision risk: Avoid defining your own array_first()/array_last() if symfony/polyfill-php85 is present—they’ll conflict at runtime. Prefer using the polyfill as the source of truth.
Attribute-only support: For DelayedTargetValidation, NoDiscard, and any future attributes, note they’re not validated at runtime by PHP < 8.5. Treat them as metadata for tooling only unless you build custom handling.
Verify via PHP_VERSION_ID: When writing dual-mode code (polyfill-aware vs native), use function_exists('array_first') or defined('PHP_VERSION_ID') && PHP_VERSION_ID >= 80500 to branch behavior safely.
How can I help you explore Laravel packages today?