Skip to content

Document the polyfill design principles#639

Merged
nicolas-grekas merged 1 commit into
1.xfrom
document-design-principles
Jul 1, 2026
Merged

Document the polyfill design principles#639
nicolas-grekas merged 1 commit into
1.xfrom
document-design-principles

Conversation

@nicolas-grekas

Copy link
Copy Markdown
Member

Refs #624.

That issue asks for the polyfill target design to be written down. This adds a "Design principles" section to the README capturing the decisions that are already applied across the codebase:

  • Backport the API of the latest PHP version to older ones; do not re-add removed/legacy behavior (e.g. the is_hex argument dropped from mb_decode_numericentity() in 8.0).
  • A polyfill reproduces the native contract of the function it shims, so ValueError-on-invalid-input functions throw on every version while false-returning ones keep returning false.
  • Bootstrap signatures match the native signature of the running PHP version; new arguments that cannot be implemented are accepted and ignored (e.g. the grapheme $locale argument in 8.5).
  • Never-bundled extensions (uuid, deepclone) follow the extension's own history, mirroring the newest native state including deprecations.
  • A function provided by both an extension polyfill and a version polyfill must behave identically.

The wording can of course be adjusted to match your intended policy.

@stof

stof commented Jul 1, 2026

Copy link
Copy Markdown
Member

I would also add the mention of constants being polyfilled only when they can produce a meaningful effect. When the constant is meant to enable a new feature in an existing function, it is better to skip polyfilling it as the effect cannot be polyfilled (and the absence of the constant can be used as feature detection).
See for instance #543 which was rejected because of that.

@nicolas-grekas

Copy link
Copy Markdown
Member Author

Good point, added a bullet: a constant whose only role is to toggle behavior in a function we can't polyfill (like FILTER_THROW_ON_FAILURE for filter_var(), ref #543) is left undefined so its absence stays usable for feature detection. I also noted the contrast with attributes, which are polyfilled because reflection still conveys their semantics without engine support.

@nicolas-grekas nicolas-grekas force-pushed the document-design-principles branch from 858b631 to aa71bd1 Compare July 1, 2026 17:57
@nicolas-grekas nicolas-grekas merged commit 3218884 into 1.x Jul 1, 2026
20 checks passed
@nicolas-grekas nicolas-grekas deleted the document-design-principles branch July 1, 2026 17:57
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.

2 participants