Repository navigation
Formatting: Document sanitize_key() as accepting mixed - #14759
westonruter wants to merge 3 commits into
Conversation
Since `sanitize_key()` guards with `is_scalar()`, it accepts any value: non-string scalars are coerced to a string, and any other type yields an empty string, as covered by its tests. Most callers pass raw request data or REST parameters, which PHPStan sees as `mixed`, so the `string` param type was reported at every such call site. * Widen `$key` to `mixed` in the function and `sanitize_key` filter docs. * Cast scalars to `string` explicitly before `strtolower()`, preserving the previous implicit coercion. * Add `@phpstan-param lowercase-string` for the filtered `$sanitized_key` so the `apply_filters()` return type matches the function's `lowercase-string` return type. * Add tests for more non-string scalars and for the arguments passed to the filter. This resolves 50 PHPStan errors at rule level 10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… provider. This also covers the arguments passed to the `sanitize_key` filter for those types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e types. The data provider now includes non-scalar types, so it is renamed from `nonstring_scalar` to `non_string`, along with the tests that use it. Cases are added for infinity, `null`, a stringable object, and a closure. A stringable object still yields an empty string, since `sanitize_key()` checks `is_scalar()`. An `Exception` is used as the stringable object because an anonymous class declared in a data provider causes PHPUnit to load the test class twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
Since a non-scalar key was made to yield an empty string in r52292 and non-string scalars were again coerced to a string in r52370, `sanitize_key()` handles values of any type, and its tests cover this. Most of its callers pass raw request data or REST parameters, which are untyped, so documenting `$key` as a `string` caused PHPStan to report an error at nearly every call site. The `sanitize_key` filter is updated to match, as it receives the original key, and its sanitized key is now typed as a lowercase string so that the result of `apply_filters()` agrees with the function's return type. The cast to `string` before `strtolower()` makes the existing coercion explicit without changing behavior. Tests are added for additional non-string types and for the arguments passed to the filter. This resolves 50 PHPStan errors at rule level 10. Developed in #14759. Follow-up to r13718, r52292, r52370. See #54160, #65817. git-svn-id: https://develop.svn.wordpress.org/trunk@64682 602fd350-edb4-49c9-b593-d223f7449a82
Since a non-scalar key was made to yield an empty string in r52292 and non-string scalars were again coerced to a string in r52370, `sanitize_key()` handles values of any type, and its tests cover this. Most of its callers pass raw request data or REST parameters, which are untyped, so documenting `$key` as a `string` caused PHPStan to report an error at nearly every call site. The `sanitize_key` filter is updated to match, as it receives the original key, and its sanitized key is now typed as a lowercase string so that the result of `apply_filters()` agrees with the function's return type. The cast to `string` before `strtolower()` makes the existing coercion explicit without changing behavior. Tests are added for additional non-string types and for the arguments passed to the filter. This resolves 50 PHPStan errors at rule level 10. Developed in WordPress/wordpress-develop#14759. Follow-up to r13718, r52292, r52370. See #54160, #65817. Built from https://develop.svn.wordpress.org/trunk@64682 git-svn-id: http://core.svn.wordpress.org/trunk@63832 1a063a9b-81f0-0310-95a4-ce76da25c4cd
✅ Committed in r64682 (eaa3b6b).
This widens the documented type of
sanitize_key()'s$keyparameter fromstringtomixed, which resolves 50 PHPStan errors at rule level 10 without introducing any.Background
The
sanitize_key()function was documented as taking astring, but it has accepted any value since r52292 (Core-54160) added a type guard to fix a PHP warning when an array was passed. Changeset r52370 then switched that guard fromis_string()tois_scalar()so that non-string scalars keep being coerced to a string bystrtolower(), as they always had been. The existing tests lock this behavior in:0→'0',true→'1',false→'',0.123→'0123'null, or an object →''So the function is total over
mixed, and that matches how it is used. Of its ~75 call sites in core, most pass raw request data ($_POST,$_GET,$_REQUEST, often throughwp_unslash()), and it is also used as a RESTsanitize_callback, as anarray_map()callback, and as apre_post_*filter callback. In all of these the value can be of any type, such as an array from?post_type[]=x.PHPStan errors resolved
At level 10 (the local
phpstan.neon), trunk reports:argument.type:Parameter #1 $key of function sanitize_key expects string, mixed given.across 19 files.argument.typeinWP_Query::parse_query():Parameter #1 $callback of function array_map expects (callable(mixed): mixed)|null, 'sanitize_key' given.return.typeinsanitize_key()itself:Function sanitize_key() should return lowercase-string but returns string.Theapply_filters()return type extension reads the type of the filter's first@param, which wasstring.A full run goes from 27,467 to 27,417 errors, with no new errors. No baselines change, since none of these errors are baselined at level 5, and
phpstan.neon.diststill reports no errors.Alternative considered:
scalarWidening to
scalar(documented asstring|int|float|boolplus@phpstan-param scalar) was tried first. It fixes only thereturn.typeerror: every call site still passesmixed, whichscalardoes not accept either, and thestrtolower()call gains a new error forbool|float|int|string. Making the call sites passscalarwould mean adding anis_scalar()check before each one, duplicating the check the function already does.Changes
$keyis documented asmixedin the function and in thesanitize_keyfilter, since the filter receives the original, unsanitized value.stringexplicitly beforestrtolower(). This preserves the prior implicit coercion.@phpstan-param lowercase-string $sanitized_key, so thatapply_filters()agrees with the function's existing@phpstan-return lowercase-string.nonstring_scalardata provider and its test are renamed tonon_string, since the provider now covers non-scalar types too.1.0E+25→'10e25', which exercises lowercasing after the cast),INF(→'inf'), an array, an object,null, a stringable object, and a closure. A stringable object still yields'', because the guard isis_scalar().sanitize_keyfilter, using the same non-string cases.Trac ticket: https://core.trac.wordpress.org/ticket/65817
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Analyzing the call sites and PHPStan errors, prototyping the
scalarandmixedalternatives, writing the change and tests, and drafting this description. Reviewed by me.This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.
🤖 Generated with Claude Code