\JsonSchema\Constraints\BaseConstraint::arrayToObjectRecursive() doesn't convert empty arrays to objects
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
(
)
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.
Strike that, it's on 6.0.0-dev, too.
Thanks - fixed in #409. This will be backported to 5.x.x after merge.
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
// (
// )
// )
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
// )
// )