json-schema
json-schema copied to clipboard
"Array value found, but an array is required"
I'm receiving this error message:
"Array value found, but an array is required"
I don't quite understand this error. It's saying that a property is an array, but it needs an array. It seems to me like it has what it wants. This error is not intuitive. Can someone explain to me what the library wants?
I think I understand what's going on. It's because it is receiving an associative PHP array but it wants an indexed array. It makes it confusing because they are the same 'type' in PHP. You actually have to go through the effort to check if you want to know if something is associative vs indexed in PHP. See: https://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential So perhaps this library should say:
" Array (with non-integer keys) value found, but an array is required."
Or something of the sort.
Can you please provide a (minimal) schema sample that produces this error?
Schema (test.json):
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
".*": {
"type": "boolean"
}
}
}
}
Data:
{"test":true}
Code:
$validator->validate(
json_decode('{"test":true}',1) // Without the "1" it's a bit more clear and says Object
,(object)['$ref' => 'file://' . realpath('./schemas/test.json')]
,Constraint::CHECK_MODE_COERCE_TYPES | Constraint::CHECK_MODE_TYPE_CAST // coerce types for the browser.
);
Output:
{"errors":[{"detail":"Array value found, but an array is required","property":""}]}
@adjenks Thanks for that - definitely looks like something we ought to improve on.
Out of curiosity, why are you forcing json_decode
to use associative arrays instead of objects? It's not the default, and it's an unusual thing to do.
I just forced json_decode to use an array to demonstrate the problem when you are already working with an array.
Hi @adjenks, I tried to make this test fail:
public function testValidateAssociativeArray()
{
$value = json_decode('{"test":true}', 1);
$schema = (object) '
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": {
"type": "object",
"patternProperties": {
".*": {
"type": "boolean"
}
}
}
}';
$validator = new Validator();
$validator->validate($value, $schema, Constraint::CHECK_MODE_COERCE_TYPES | Constraint::CHECK_MODE_TYPE_CAST);
}
but it doesn't. On which PHP version are you? I'm on PHP 7.2.
@antodippo You can't cast a string to an object the way you are attempting to do - you just end up with an StdClass
object containing a single string property, which obviously is not a sane schema.
Use json_decode()
, not (object)
casting.
To clarify - the object that results from using (object)
on a string is essentially an empty schema, against which any input is considered valid.
@antodippo I was using whatever the newest PHP version was when I made the post. erayd is correct, you can't turn a string into an object. PHP tries to but it makes no sense. See this example:
php > $a = (object)'{"testing":123}';
php > var_export($a);
stdClass::__set_state(array(
'scalar' => '{"testing":123}',
))
php > echo $a;
PHP Recoverable fatal error: Object of class stdClass could not be converted to string in php shell code on line 1
php > echo $a->testing;
PHP Notice: Undefined property: stdClass::$testing in php shell code on line 1
So it's not a string anymore, and it's also not a a decoded json-object. So although casting a string to an object does not initially throw an error, I'm not sure what it's useful for.
Hi,
I have the same problem :
hydra:member[0]: Array value found, but an object is required
My json is :
{
"@id":"\/product_variants",
"@type":"hydra:Collection",
"hydra:member":[
{
"@id":"\/product_variants\/my_product",
"@type":"ProductVariant",
"code":"my_product",
"position":0,
"createdAt":"2019-08-05T16:09:13+00:00",
"updatedAt":null,
"optionsValues":[
{
"@id":"\/product_option_values\/1",
"code":"age_class_children",
"optionCode":"age_class",
"position":0
},
{
"@id":"\/product_option_values\/3",
"code":"class_ordinary",
"optionCode":"class",
"position":1
},
{
"@id":"\/product_option_values\/5",
"code":"duration_seven",
"optionCode":"duration",
"position":2
}
]
}
]
}
And my simplified shcema in order to get the error :
{
"type": "object",
"required": [
"@id",
"@type",
"hydra:member"
],
"properties": {
"hydra:member": {
"type": "array",
"items": {
"type": "object",
"required": [
"@id",
"@type",
"code",
"position",
"createdAt",
"updatedAt",
"optionsValues"
]
}
}
}
}
How can we validate a collection of object ?
EDIT : sorry it's not really the same issue. If I indicate that my type is an array for my hydra:member items, the schema is valid. But for me this should be an object.