Skip to content

Guard iterator_to_array() against being declared twice - #7

Draft
Steveb-p wants to merge 1 commit into
mainfrom
guard-against-double-declaration
Draft

Guard iterator_to_array() against being declared twice#7
Steveb-p wants to merge 1 commit into
mainfrom
guard-against-double-declaration

Conversation

@Steveb-p

@Steveb-p Steveb-p commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator
🎫 Issue IBX-XXXXX

Related PRs:

Description:

src/iterator_to_array.php is loaded eagerly through composer's autoload.files, but it also sits
inside the directory autoload.psr-4 maps Ibexa\PolyfillPhp82\ to. So anything resolving
Ibexa\PolyfillPhp82\iterator_to_array as a class name makes the autoloader include the file a
second time, and without a guard that's fatal:

PHP Fatal error: Cannot redeclare Ibexa\PolyfillPhp82\iterator_to_array()
(previously declared in .../src/iterator_to_array.php:18)

Static analysers probing an imported function are the common trigger. PHPStan hits it in any
package that writes use function Ibexa\PolyfillPhp82\iterator_to_array; — it dies before
reporting anything, so the job fails with an error unrelated to the code under test. ibexa/test-core
is currently red on PHP 7.4 for exactly this, on every PR against 4.6 regardless of contents.

Wrapping the declaration in function_exists() makes the second include a harmless no-op, which is
how symfony/polyfill handles its own function files. testDeclarationFileCanBeLoadedTwice covers
it — I checked it reproduces the fatal above with the guard stashed, so it's a real regression test
rather than a green one.

I left the autoload.files / autoload.psr-4 overlap alone. Narrowing PSR-4 away from this file
would also fix it, but the guard is the smaller change and covers any other path that ends up
including the file twice.

src/iterator_to_array.php is loaded eagerly through composer's "autoload.files", but it also sits
inside the directory "autoload.psr-4" maps Ibexa\PolyfillPhp82\ to. Anything that resolves
"Ibexa\PolyfillPhp82\iterator_to_array" as a *class* name therefore makes the autoloader include
the file a second time, and without a guard that's fatal:

    PHP Fatal error: Cannot redeclare Ibexa\PolyfillPhp82\iterator_to_array()
    (previously declared in .../src/iterator_to_array.php:18)

Static analysers probing an imported function are the common trigger. PHPStan hits it in any
package that writes `use function Ibexa\PolyfillPhp82\iterator_to_array;` -- it dies before
reporting anything, so the analysis job fails with an error that has nothing to do with the code
under test. ibexa/test-core is currently red on PHP 7.4 for exactly this reason.

Wrapping the declaration in function_exists() makes the second include a harmless no-op, which is
how symfony/polyfill handles its own function files. Added a regression test that requires the
file a second time; it reproduces the fatal above without this change.

Leaving the autoload.files / autoload.psr-4 overlap in place -- narrowing PSR-4 away from this
file would work too, but the guard is the smaller change and protects against any other path that
ends up including it twice.
@Steveb-p
Steveb-p force-pushed the guard-against-double-declaration branch from f5c1720 to 590fa30 Compare September 8, 2026 21:11
@Steveb-p
Steveb-p marked this pull request as ready for review September 8, 2026 21:28
Steveb-p added a commit to ibexa/test-core that referenced this pull request Sep 8, 2026
…82#7

PHPStan dies on PHP 7.4 before reporting anything -- "Cannot redeclare
Ibexa\PolyfillPhp82\iterator_to_array() ... while running parallel worker" -- so this job fails on
every PR against 4.6 regardless of contents. Points CI at the branch that guards the declaration.
Must be removed before merging.
Steveb-p added a commit to ibexa/test-core that referenced this pull request Sep 8, 2026
…82#7

PHPStan dies on PHP 7.4 before reporting anything -- "Cannot redeclare
Ibexa\PolyfillPhp82\iterator_to_array() ... while running parallel worker" -- so this job fails on
every PR against 4.6 regardless of contents. Points CI at the branch that guards the declaration.
Must be removed before merging.
@Steveb-p
Steveb-p marked this pull request as draft September 8, 2026 21:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant