-
Notifications
You must be signed in to change notification settings - Fork 183
Constructor property promotion not working correctly with properties that start with the same characters as the json property #242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
My analysis shows the surprising fact that annotations still take precedence over actual types assigned. But I can reproduce the error, and it is correct that the search for the annotation simply scans for "string containing $+key" in the annotation array, without checking that there might be nonwhitespace after "key" in the property name. I would love to fix the precedence issue here first. If proper types are assigned, they are valid and required to be followed, as you'd be unable to assign an "IdType" to a field requiring "string" and vice versa. And then, you'd still need to update to version 5.0, which isn't a big step, but might require setting a flag back to it's previous default. As a workaround, if you'd not include the annotation at all, i.e. remove the last asterisk in |
I agree that the precedence is more important here.
I'm not sure how big the changes are in 5.0
Yes, but then i will lose some phpdoc functionality in me IDE (Phpstorm) since it can't parse the docblock. |
I did some testing and found another weird thing This script enum IdType: string {
case email = "email";
case other = "other";
}
readonly class SomeClass
{
/**
* @param string $firstName First name of the recipient.
* @param string $lastName Last name of the recipient.
* @param IdType $idType The recipient ID type. This is used to indicate the format used for the ID.
* @param string $nickname Nickname or display name of the recipient.
* @param string $id The recipient ID specific to the provider.
*/
public function __construct(
public string $firstName,
public string $lastName,
public IdType $idType,
public string $nickname,
public string $id
) {}
}
$mapper = new JsonMapper();
$mapper->bExceptionOnMissingData = true;
$jsonObject = json_decode('{
"id": "[email protected]",
"idType": "email"
}');
try {
$result = $mapper->map($jsonObject, SomeClass::class);
var_dump($result);
} catch(JsonMapper_Exception $e) {
echo $e->getMessage();
} Results in
But if i simply change
i get
i was expecting the same error but somehow it now correctly understands the order? |
I tested this and it works but not completely Replacing the
Inspection on the property works fine Inspection on the constructor does not (it doesn't show the descriptions correctly) The most important part works; showing the description when accessing the properties, so i'll use this as a workaround for now. |
I believe we uncovered two issues here - at least that's what I found yesterday:
To keep this from happening, we'd need a proper test case, but I'll try to do my best there. Hint: The reason I mentioned version 5 is because I don't think there will be maintenance releases for earlier versions, even if there are gaps in the version numbers. As major versions don't increase the required PHP version as of now, that should not be a big issue. |
I like to add another problem: Even though JSON allows to distinguish between strings, ints and floats, the JsonMapper will call |
Uh oh!
There was an error while loading. Please reload this page.
Running
netresearch/jsonmapper: 4.5.0
Consider the following class
And this is my json payload
When running
it tries to put
"id": "[email protected]"
into$idType
which will fail because"[email protected]"
is not a valid value for enumIdType
.This is because of the following check https://github.com/cweiske/jsonmapper/blob/v4.5.0/src/JsonMapper.php#L580-L588
It seems to match
$id
to$idType
because it starts with$id
which is wrong in this case.It should check if the whole variable name matches, so that
"$id" does not match "$idType".
Another thing is if my docblock contains
$id
somewhere in the description it would still matchThis would match for the json key
id
.The text was updated successfully, but these errors were encountered: