Skip to content

Instantly share code, notes, and snippets.

@mtdowling
Created March 29, 2017 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtdowling/ed5ea633ec8358e6d2d399a8c0aa1220 to your computer and use it in GitHub Desktop.
Save mtdowling/ed5ea633ec8358e6d2d399a8c0aa1220 to your computer and use it in GitHub Desktop.
Check if a value can be json_decoded
<?php
function try_json_encode($data)
{
json_encode($data);
return (json_last_error() == JSON_ERROR_NONE);
}
function json_encode_type_check($data)
{
static $validTypes = [
'string' => true,
'integer' => true,
'double' => true,
'boolean' => true,
'array' => true,
'null' => true,
];
$type = gettype($data);
return isset($validTypes[$type])
|| $type == 'object' and $data instanceof JsonSerializable;
}
function benchmark($f, $iterations, ...$args)
{
$startTime = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$f(...$args);
}
return ((microtime(true) - $startTime) / $iterations) * 1e9;
}
$iterations = 10000;
$cases = [
'associative' => ['foo' => ['bar', 'baz', ['bam' => false]]],
'boolean' => true,
'string' => 'foobaz',
'number' => -1,
'deep assoc' => ['foo' => ['bar', 'baz', ['bam' => false]], ['foo' => ['bar', 'baz', ['bam' => false]]]],
];
$benches = ['try_json_encode', 'json_encode_type_check'];
foreach ($cases as $caseName => $case) {
foreach ($benches as $bench) {
$result = benchmark($bench, $iterations, $case);
printf("%-20s %-30s: %-20f ns/iter\n", $caseName, $bench, $result);
}
echo "----\n";
}
@mtdowling
Copy link
Author

mtdowling commented Mar 29, 2017

Example output:

associative          try_json_encode               : 630.497932           ns/iter
associative          json_encode_type_check        : 306.200981           ns/iter
----
boolean              try_json_encode               : 198.483467           ns/iter
boolean              json_encode_type_check        : 634.384155           ns/iter
----
string               try_json_encode               : 243.020058           ns/iter
string               json_encode_type_check        : 376.105309           ns/iter
----
number               try_json_encode               : 348.401070           ns/iter
number               json_encode_type_check        : 248.122215           ns/iter
----
deep assoc           try_json_encode               : 813.007355           ns/iter
deep assoc           json_encode_type_check        : 308.108330           ns/iter
----

@imshashank
Copy link

imshashank commented Mar 29, 2017

There can be objects wich are not instances of JsonSerializable which can be json_encoded.

<?php

$obj = new StdClass();

$obj->a = "b";

var_dump($obj instanceof JsonSerializable);
var_dump(json_encode($obj));

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