Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Polyfill Util Laravel Package

symfony/polyfill-util

A small Symfony utility polyfill that provides shared helper classes and functions used by other Symfony polyfill packages. It is not intended for direct use; include it when a polyfill depends on it to support compatibility across PHP versions.

Deep Wiki
Context7

Getting Started

Do not composer require this package. symfony/polyfill-util is an internal shim that exists so other Symfony polyfills and legacy components can behave consistently on ancient PHP runtimes. Ninety-nine percent of the time you see it in a project, it arrived transitively and you should never name it in a composer.json.

First commands to run:

composer why symfony/polyfill-util      # Composer 2.x (alias: composer depends)
composer show symfony/polyfill-util     # installed version + description

If nothing claims it as a direct dependency, it is implementation detail — treat it like a compiled artifact, not an API.

Where to look first. The package is deliberately tiny: open vendor/symfony/polyfill-util/ and read the whole src/ directory plus composer.json in one sitting. Pay attention to the autoload block — this package has historically used a classmap, which means stale optimized autoloaders (composer dump-autoload -o) can be the cause of "class not found" surprises. You are looking for the stream-wrapper class (the "binary on colon" helper) whose job is to make binary read/write modes work on php:// stream URLs on runtimes where the core implementation is deficient.

First real use case. You are keeping a legacy application alive on an old PHP branch, and something calls:

$fp = fopen('php://temp', 'w+b');

…and the handle comes back false or misbehaves because the b flag is not honoured by the platform's php:// wrapper. The package lets you register a replacement wrapper once at bootstrap and leave every other fopen/file_get_contents call in the codebase untouched. The second common case is simply unblocking composer update on an old runtime where a Symfony component declares the polyfill in require.

Implementation Patterns

Register once, at the outermost edge. Bootstrap the wrapper in your front controller, AppServiceProvider::register(), or a Composer files autoload entry — never in library code, and never twice:

if (PHP_VERSION_ID < 70000 && !in_array('php', stream_get_wrappers(), true)) {
    \Symfony\Polyfill\Util\BinaryOnColon::register(); // static entry point, verify signature in src/
}

Guard on PHP_VERSION_ID first, registration state second. On PHP 7+ the whole package is dead weight and should be short-circuited.

Quarantine it behind your own function. If application code genuinely needs the behaviour, do not sprinkle the polyfill class through your domain logic. Write one adapter:

function binary_temp_stream(): resource
{
    $fp = @fopen('php://temp', 'w+b');
    if ($fp === false) {
        throw new \RuntimeException('Unable to open binary temp stream');
    }

    return $fp;
}

That function is the only place that knows the polyfill exists, which makes the eventual removal a one-file change.

Test-suite usage. Polyfill packages are frequently pulled in only because a test harness or fixture loader writes binary content (uploaded files, multipart bodies, ZIP fixtures). In that case, keep it in require-dev at the root and let the production graph stay clean.

CI matrix pattern. Split the job:

legacy:
  php: 5.6
  install: composer update --prefer-lowest
modern:
  php: 8.3
  install: composer update

Only the legacy lane actually exercises the polyfill; the modern lane proves you can delete it. Run the modern lane with composer update --no-dev and grep the lock file to confirm the package is gone.

Monorepo / library publishing. If you ship a library, never add this to require. Either declare "replace": {"symfony/polyfill-util": "*"} when you have inlined the behaviour, or simply raise your php constraint and let consumers drop the branch. Pinning it explicitly in a library is how you end up in dependency-hell conversations with downstream users.

Upgrade path as a workflow. Treat every major PHP bump as a scheduled task: run composer why, delete the manual registration, run the test suite, then composer remove symfony/polyfill-util if it was a root requirement. Do it in the same PR as the php platform bump so the reviewer sees the causality.

Gotchas and Tips

  • Stream wrappers are process-global. Registering twice throws a warning or silently shadows your own wrapper. Always check stream_get_wrappers() before calling the registration helper, and be aware that another library (or a test bootstrap file) may have registered php already.
  • You are shadowing a core scheme. Once you register a php wrapper you own php://temp, php://memory, php://stdin, and friends for the rest of the request. If the polyfill's stream_stat(), stream_eof(), stream_seek(), or stream_tell() implementations differ from core — and they will, subtly — fstat(), rewind(), and feof() can behave differently than your tests assume. Assert on stream_get_meta_data($fp) rather than trusting fopen success alone.
  • The b flag is meaningless on Unix. Every failure mode here is Windows-only or HHVM-only. If your CI is Linux-only you will ship a wrapper that has never been exercised. Use stream_get_meta_data($fp)['mode'] for assertions, not flock-style side effects.
  • Mode-string parsing is the whole bug surface. r+b, wb, w+b, and a+b all funnel through the wrapper's mode parser. Test the full matrix; do not assume r and rb behave the same after registration.
  • Classmap autoloading. Because classes are classmap'd rather than PSR-4 mapped, renaming or relocating files inside vendor/ (which you shouldn't do anyway) fails silently until first use. After any composer update, run composer dump-autoload -o in deploy scripts.
  • Abandoned/legacy status. Metadata such as future-dated releases and a very high transitive install count relative to direct usage are signals of automated maintenance, not active development. Do not expect security patches. Run composer audit and, if you are strict, add an allow-plugins/ignore rule or a replace in your own package.
  • Static analysis noise. PHPStan/Psalm will flag the polyfill classes because they are conditionally loaded and reference PHP-version-specific signatures. Exclude vendor/symfony/polyfill-util explicitly or, better, add a stub in stubs/ so IDE completion does not autocomplete these internals into your code.
  • Debugging checklist, in order: stream_get_wrappers() (is it registered?), stream_get_meta_data($fp) (what mode did you actually get?), stream_get_contents($fp, -1, 0) (is anything there?), then error_get_last() (was there a suppressed warning from fopen?).
  • Extension points are effectively zero. There is no config object, no DI extension, no events. The only lever you have is whether the wrapper is registered, and when. Anything more elaborate belongs in your own code, not here.
  • Removal tip. When you finally drop old PHP support, search the codebase for the package namespace before deleting vendor: a stray use Symfony\Polyfill\Util\... will fatal at runtime, not at composer remove time.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings