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

\JsonSchema\Constraints\BaseConstraint::arrayToObjectRecursive() doesn't convert empty arrays to objects #407

Open
shtrom opened this issue Apr 5, 2017 · 5 comments
Labels

Comments

@shtrom
Copy link

shtrom commented Apr 5, 2017

When an empty array is given to \JsonSchema\Constraints\BaseConstraint::arrayToObjectRecursive(), it is returned identical. This leads to issues later on when using a SchemaStorage to contain this schema. Such an empty schema is only really used for tests, but this currently requires workarounds.

The following example code

use \JsonSchema\Validator;
print_r(Validator::arrayToObjectRecursive([ "baz" => [ "bar" => "baz" ]  ])); 
print_r(Validator::arrayToObjectRecursive([]));

results in

stdClass Object
(
    [baz] => stdClass Object
        (
            [bar] => baz
        )

)
Array
(
)
@shtrom
Copy link
Author

shtrom commented Apr 5, 2017

Hum, this seems to only be on the 5.x.x branch.

Adding cast to (object) before (well, after the keyword) the return in https://github.com/justinrainbow/json-schema/blob/5.x.x/src/JsonSchema/Constraints/BaseConstraint.php#L146 seems to fix the issue.

@shtrom
Copy link
Author

shtrom commented Apr 5, 2017

Strike that, it's on 6.0.0-dev, too.

@erayd
Copy link
Contributor

erayd commented Apr 5, 2017

Thanks - fixed in #409. This will be backported to 5.x.x after merge.

@wotnak
Copy link

wotnak commented Sep 9, 2023

The issue was fixed for passing an empty array directly, but still persists for nested empty arrays.

// Directly passing an empty array.
$array = [];
$object = \JsonSchema\Validator::arrayToObjectRecursive($array);
print_r($object);
// stdClass Object
// (
// )
// Passing a nested empty array.
$array = ['shouldBeAnObject' => []];
$object = \JsonSchema\Validator::arrayToObjectRecursive($array);
print_r($object);
// stdClass Object
// (
//     [shouldBeAnObject] => Array
//         (
//         )
// )

It could be fixed by passing JSON_FORCE_OBJECT flag to json_encode used in arrayToObjectRecursive method.
https://github.com/justinrainbow/json-schema/blob/master/src/JsonSchema/Constraints/BaseConstraint.php#L145
https://www.php.net/manual/en/function.json-encode.php
https://www.php.net/manual/en/json.constants.php#constant.json-force-object

--- a/src/JsonSchema/Constraints/BaseConstraint.php
+++ b/src/JsonSchema/Constraints/BaseConstraint.php
@@ -142,7 +142,7 @@ class BaseConstraint
      */
     public static function arrayToObjectRecursive($array)
     {
-        $json = json_encode($array);
+        $json = json_encode($array, \JSON_FORCE_OBJECT);
         if (json_last_error() !== \JSON_ERROR_NONE) {
             $message = 'Unable to encode schema array as JSON';
             if (function_exists('json_last_error_msg')) {
// Passing a nested empty array after adding JSON_FORCE_OBJECT flag.
$array = ['shouldBeAnObject' => []];
$object = \JsonSchema\Validator::arrayToObjectRecursive($array);
print_r($object);
// stdClass Object
// (
//     [shouldBeAnObject] => stdClass Object
//         (
//         )
// )

@wotnak
Copy link

wotnak commented Sep 9, 2023

Although, adding JSON_FORCE_OBJECT flag would also change how nested not empty not associative arrays are treated, so probably not the best solution.

// Currently.
$array = ['key' => ['value1', 'value2']];
$object = \JsonSchema\Validator::arrayToObjectRecursive($array);
// stdClass Object
// (
//     [key] => Array
//         (
//             [0] => value1
//             [1] => value2
//         )
// )
// After adding JSON_FORCE_OBJECT flag.
$array = ['key' => ['value1', 'value2']];
$object = \JsonSchema\Validator::arrayToObjectRecursive($array);
// stdClass Object
// (
//     [key] => stdClass Object
//         (
//             [0] => value1
//             [1] => value2
//         )
// )

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

No branches or pull requests

4 participants