Kevin Lopez addressed Larry and Ilija in a PHP Internals discussion about the draft Pattern Matching RFC. He maintains a production PHP application that rejects a model's JSON response when a field is missing or has the wrong type. Lopez says the current draft could accept two responses that this application must reject.
<?php
function partQuote(array $p): ?array {
if (!is_string($p['part'] ?? null)) {
return null;
}
if (array_key_exists('quote', $p) && $p['quote'] !== null && !is_string($p['quote'])) {
return null;
}
$out = ['part' => $p['part']];
if (array_key_exists('quote', $p)) {
$out['quote'] = $p['quote']; // null is kept; the key was present
}
return $out;
}The RFC's array-pattern rules use array_key_exists() before comparing a value. An implementation note in php/php-src pull request 20574 says the draft reads a missing element as null. That would make `['a' => 42]` match `['b' => null]`. Lopez asks the authors to keep the existing RFC wording because his parser treats an absent key and a present key containing null as different states.
His `partQuote()` example requires `part` to be a string. `quote` may be absent, null, or a string, but another type returns null. The output keeps the `quote` key when it was supplied. As a result, `partQuote(['part' => 'A'])` returns `['part' => 'A']`. A call with `quote` set to null keeps that key in the output. A numeric quote returns null.
The second issue concerns a score-like field. The parser requires `strength` to pass is_int() before applying the inclusive 0 through 100 range. `'80'` fails because it is a string, and `80.0` fails because it is a float. `101` is outside the range. For `relevant`, the same no-coercion rule uses is_bool(): both `1` and `'true'` fail. `strength` 80 together with `relevant` true passes. Lopez says an int pattern and a range pattern such as `>=0 & <=100` must reject numeric strings and floats when used for this field. He is asking for the existing rules to be applied consistently, not for new syntax.




Comments
No comments yet — be the first.
Open the discussion
No account or password needed — just enter your e-mail and we’ll send you a one-time sign-in link. First time here? You’re set up automatically.
Your rating will be applied automatically after you sign in.
Check your inbox
We’ve sent a sign-in link to …. Open it on this device — this tab will sign you in automatically.
Nothing arrived? Check your spam folder — and mark the mail as "Not spam" so it lands in your inbox next time.