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.

partQuote.php
<?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.