Skip to content

Instantly share code, notes, and snippets.

@danrspencer
Last active April 29, 2021 06:43
Show Gist options
  • Save danrspencer/9753d0d25e07da01b47cb50f60a76958 to your computer and use it in GitHub Desktop.
Save danrspencer/9753d0d25e07da01b47cb50f60a76958 to your computer and use it in GitHub Desktop.
Validate a PHP array against a schema to ensure all desired keys are present (supports nested)
function validateAgainstSchema(array $schema, $data) {
$valid = true;
$done = false;
$path = "";
$current = each($schema);
while($valid !== false && $current !== false) {
list($key, $value) = $current;
$index = is_string($key) ? $key : $value;
$valid = isset($data[$index]);
$path = $index;
if ($valid && is_array($value)) {
list($valid, $index) = validateAgainstSchema($value, $data[$key]);
$path .= ".$index";
}
if ($valid) $current = each($schema);
}
return [ $valid, $valid ? "" : $path ];
}
@danrspencer
Copy link
Author

Example usage:

$exampleSchema = [
  "id",
  "name" => [
    "first",
    "second"
  ],
  "age"
];

$array1 = [
  "id" => 1,
  "name" => [ "first" => "Dan", "second" => "Spencer" ],
  "age" => 33
];
list($valid, $path) = validateAgainstSchema($exampleSchema, $array1);
echo($valid ? "Valid array\n" : "Invalid array, missing: $path\n");
// Output: Valid array

$array2 = [
  "id" => 1,
  "name" => [ "first" => "Dan" ],
  "age" => 33
];
list($valid, $path) = validateAgainstSchema($exampleSchema, $array2);
echo($valid ? "Valid array\n" : "Invalid array, missing: $path\n");
// Output: Invalid array, missing: name.second

@ludwig-gramberg
Copy link

someone once invented classes ...

@combatwombat
Copy link

And writing a class for every small data structure is awesome if you're paid hourly.

@cjgarciaj
Copy link

Nice gist but I'll just leave here an array to add some complexity to the matter:

[
  "list_number" => 1,
  "items" => [[ "value" => 1552.22 ], [ "value" => 155.22 ]],
  "total" => 33
]

The items should be more JSON, like {[],[],...,[]} but I think my point is clear.
Thanks for reading ^~^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment