Skip to content
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

"Array value found, but an array is required" #523

Open
adjenks opened this issue Jul 18, 2018 · 10 comments
Open

"Array value found, but an array is required" #523

adjenks opened this issue Jul 18, 2018 · 10 comments

Comments

@adjenks
Copy link

adjenks commented Jul 18, 2018

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?

@adjenks
Copy link
Author

adjenks commented Jul 18, 2018

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.

@shmax
Copy link
Collaborator

shmax commented Jul 19, 2018

Can you please provide a (minimal) schema sample that produces this error?

@adjenks
Copy link
Author

adjenks commented Jul 19, 2018

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":""}]}

@erayd
Copy link
Collaborator

erayd commented Jul 19, 2018

@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.

@adjenks
Copy link
Author

adjenks commented Jul 19, 2018

I just forced json_decode to use an array to demonstrate the problem when you are already working with an array.

@antodippo
Copy link

antodippo commented Oct 30, 2018

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.

@erayd
Copy link
Collaborator

erayd commented Oct 30, 2018

@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.

@erayd
Copy link
Collaborator

erayd commented Oct 30, 2018

To clarify - the object that results from using (object) on a string is essentially an empty schema, against which any input is considered valid.

@adjenks
Copy link
Author

adjenks commented Oct 30, 2018

@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.

@FabienSalles
Copy link

FabienSalles commented Aug 6, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants