[php] fix: enumUnknownDefaultCase declares the unknown-default member but never deserializes to it
With enumUnknownDefaultCase=true, the php client adds UNKNOWN_DEFAULT_OPEN_API to every enum class, but ObjectSerializer::deserialize still throws for a $ref'd enum. The error message even lists the member it refuses to return:
InvalidArgumentException: Invalid value for enum 'OpenAPI\Client\Model\DomainStatus', must be one of: 'ACTIVE', 'INACTIVE', 'unknown_default_open_api'
#20594 fixed inline enum properties only; a $ref'd enum is its own class and is rejected in ObjectSerializer before any model sees it. Reproduced on current master.
Fix
ObjectSerializer.mustache, the enum branch of deserialize:
{{#enumUnknownDefaultCase}}
if (defined("$class::UNKNOWN_DEFAULT_OPEN_API")) {
return constant("$class::UNKNOWN_DEFAULT_OPEN_API");
}
{{/enumUnknownDefaultCase}}
The branch is generated only with the flag, and at runtime it applies only to enum classes that declare the constant. Output without the flag is byte-identical.
Verification (php 8, DomainStatus: [ACTIVE, INACTIVE], Domain.status: $ref, flag on)
| master | this PR | |
|---|---|---|
deserialize('SOMETHING_NEW', DomainStatus::class) | throws InvalidArgumentException | returns 'unknown_default_open_api' |
deserialize(payload, Domain::class) with status: "SOMETHING_NEW" | throws InvalidArgumentException | getStatus() returns 'unknown_default_open_api' |
Tests
The two PhpClientCodegenTest cases from #20594 now also check the generated ObjectSerializer.php: the fallback is present with the flag (fails without the fix) and absent without it.
Known gaps
php-nextgen has the same defect, but its enums are native \BackedEnums, so the fix needs different mechanics and a separate PR.
PR checklist
- Read the contribution guidelines.
- Built the project and updated samples (
./bin/generate-samples.sh ./bin/configs/php*.yaml). No sample changed: none enablesenumUnknownDefaultCase. - Technical committee: @jebentier @dkarlovi @mandrean @jfastnacht @ybelenko @renepardon
Summary by cubic
Fixes PHP enum deserialization when enumUnknownDefaultCase is enabled: unrecognized enum values now return the unknown-default member instead of throwing InvalidArgumentException.
- The fallback in
ObjectSerializer::deserializereturns the enum'sUNKNOWN_DEFAULT_OPEN_APIconstant only when that constant is defined, and only in clients generated with the flag; other clients are byte-identical. - Adds tests covering both enabled and disabled flag states.
Generated with Claude Code