print json_encode ejemplo array acceder php json error-handling json-deserialization jsonresult

json_encode - ¿La forma más rápida de verificar si una cadena es JSON en PHP?



print json php (26)

Necesito un método realmente rápido para verificar si una cadena es JSON o no. Siento que esta no es la mejor manera:

function isJson($string) { return ((is_string($string) && (is_object(json_decode($string)) || is_array(json_decode($string))))) ? true : false; }

¿Algún entusiasta del rendimiento por ahí quiere mejorar este método?


Respuesta a la pregunta

La función json_last_error devuelve el último error ocurrido durante la codificación y decodificación JSON. Así que la forma más rápida de verificar el JSON válido es

// decode the JSON data // set second parameter boolean TRUE for associative array output. $result = json_decode($json); if (json_last_error() === JSON_ERROR_NONE) { // JSON is valid } // OR this is equivalent if (json_last_error() === 0) { // JSON is valid }

Tenga en cuenta que json_last_error es compatible con PHP> = 5.3.0.

Programa completo para verificar el ERROR exacto

Siempre es bueno saber el error exacto durante el tiempo de desarrollo. Aquí está el programa completo para verificar el error exacto basado en documentos PHP.

function json_validate($string) { // decode the JSON data $result = json_decode($string); // switch and check possible JSON errors switch (json_last_error()) { case JSON_ERROR_NONE: $error = ''''; // JSON is valid // No error has occurred break; case JSON_ERROR_DEPTH: $error = ''The maximum stack depth has been exceeded.''; break; case JSON_ERROR_STATE_MISMATCH: $error = ''Invalid or malformed JSON.''; break; case JSON_ERROR_CTRL_CHAR: $error = ''Control character error, possibly incorrectly encoded.''; break; case JSON_ERROR_SYNTAX: $error = ''Syntax error, malformed JSON.''; break; // PHP >= 5.3.3 case JSON_ERROR_UTF8: $error = ''Malformed UTF-8 characters, possibly incorrectly encoded.''; break; // PHP >= 5.5.0 case JSON_ERROR_RECURSION: $error = ''One or more recursive references in the value to be encoded.''; break; // PHP >= 5.5.0 case JSON_ERROR_INF_OR_NAN: $error = ''One or more NAN or INF values in the value to be encoded.''; break; case JSON_ERROR_UNSUPPORTED_TYPE: $error = ''A value of a type that cannot be encoded was given.''; break; default: $error = ''Unknown JSON error occured.''; break; } if ($error !== '''') { // throw the Exception or exit // or whatever :) exit($error); } // everything is OK return $result; }

Pruebas con la entrada JSON válida

$json = ''[{"user_id":13,"username":"stack"},{"user_id":14,"username":"over"}]''; $output = json_validate($json); print_r($output);

SALIDA VÁLIDA

Array ( [0] => stdClass Object ( [user_id] => 13 [username] => stack ) [1] => stdClass Object ( [user_id] => 14 [username] => over ) )

Pruebas con JSON inválido

$json = ''{background-color:yellow;color:#000;padding:10px;width:650px;}''; $output = json_validate($json); print_r($output);

SALIDA VÁLIDA

Syntax error, malformed JSON.

Nota adicional para (PHP> = 5.2 && PHP <5.3.0)

Dado que json_last_error no es compatible con PHP 5.2, puede verificar si la codificación o decodificación devuelve FALSE booleano. Aquí hay un ejemplo

// decode the JSON data $result = json_decode($json); if ($result === FALSE) { // JSON is invalid }

Espero que esto sea de ayuda. ¡Feliz codificación!


Ampliando en esta respuesta ¿Qué hay de lo siguiente:

<?php $json = ''[{"user_id":13,"username":"stack"},{"user_id":14,"username":"over"}]''; //$json = ''12''; function isJson($string) { json_decode($string); if(json_last_error() == JSON_ERROR_NONE) { if(substr($string,0,1) == ''['' && substr($string,-1) == '']'') { return TRUE; } else if(substr($string,0,1) == ''{'' && substr($string,-1) == ''}'') { return TRUE; } else { return FALSE; } } } echo isJson($json); ?>


Anteriormente estaba comprobando un valor nulo, que en realidad estaba equivocado.

$data = "ahad"; $r_data = json_decode($data); if($r_data){//json_decode will return null, which is the behavior we expect //success }

El código anterior funciona bien con cuerdas. Sin embargo, tan pronto como proporciono el número, se rompe. Por ejemplo.

$data = "1213145"; $r_data = json_decode($data); if($r_data){//json_decode will return 1213145, which is the behavior we don''t expect //success }

Para arreglarlo lo que hice fue muy simple.

$data = "ahad"; $r_data = json_decode($data); if(($r_data != $data) && $r_data) print "Json success"; else print "Json error";


Debe validar su entrada para asegurarse de que la cadena que pasa no esté vacía y, de hecho, es una cadena. Una cadena vacía no es JSON válida.

function is_json($string) { return !empty($string) && is_string($string) && is_array(json_decode($string, true)) && json_last_error() == 0; }

Creo que en PHP es más importante determinar si el objeto JSON tiene datos, porque para usar los datos deberá llamar a json_encode() o json_decode() . Sugiero negar objetos JSON vacíos para que no esté ejecutando codificaciones y decodificaciones innecesariamente en datos vacíos.

function has_json_data($string) { $array = json_decode($string, true); return !empty($string) && is_string($string) && is_array($array) && !empty($array) && json_last_error() == 0; }


Esto devolverá verdadero si su cadena representa una matriz u objeto json :

function isJson($str) { $json = json_decode($str); return $json && $str != $json; }

Rechaza las cadenas json que solo contienen un número, una cadena o un valor booleano, aunque esas cadenas son técnicamente válidas.

var_dump(isJson(''{"a":5}'')); // bool(true) var_dump(isJson(''[1,2,3]'')); // bool(true) var_dump(isJson(''1'')); // bool(false) var_dump(isJson(''1.5'')); // bool(false) var_dump(isJson(''true'')); // bool(false) var_dump(isJson(''false'')); // bool(false) var_dump(isJson(''null'')); // bool(false) var_dump(isJson(''hello'')); // bool(false) var_dump(isJson('''')); // bool(false)

Es el camino más corto que se me ocurre.


Esto lo hará:

function isJson($string) { $decoded = json_decode($string); if ( !is_object($decoded) && !is_array($decoded) ) { return false; } return (json_last_error() == JSON_ERROR_NONE); } if ( isJson($someJsonString) ) { echo "valid JSON"; } else { echo "not valid JSON"; }


Función recién creada para la compatibilidad con PHP 5.2, si necesita que los datos descodificados sean exitosos:

function try_json_decode( $json, & $success = null ){ // non-strings may cause warnings if( !is_string( $json )){ $success = false; return $json; } $data = json_decode( $json ); // output arg $success = // non-null data: success! $data !== null || // null data from ''null'' json: success! $json === ''null'' || // null data from '' null '' json padded with whitespaces: success! preg_match(''/^/s*null/s*$/'', $json ); // return decoded or original data return $success ? $data : $json; }

Uso:

$json_or_not = ...; $data = try_json_decode( $json_or_not, $success ); if( $success ) process_data( $data ); else what_the_hell_is_it( $data );

Algunas pruebas:

var_dump( try_json_decode( array(), $success ), $success ); // ret = array(0){}, $success == bool(false) var_dump( try_json_decode( 123, $success ), $success ); // ret = int(123), $success == bool(false) var_dump( try_json_decode('' '', $success ), $success ); // ret = string(6) " ", $success == bool(false) var_dump( try_json_decode( null, $success ), $success ); // ret = NULL, $success == bool(false) var_dump( try_json_decode(''null'', $success ), $success ); // ret = NULL, $success == bool(true) var_dump( try_json_decode('' null '', $success ), $success ); // ret = NULL, $success == bool(true) var_dump( try_json_decode('' true '', $success ), $success ); // ret = bool(true), $success == bool(true) var_dump( try_json_decode('' "hello" '', $success ), $success ); // ret = string(5) "hello", $success == bool(true) var_dump( try_json_decode('' {"a":123} '', $success ), $success ); // ret = object(stdClass)#2 (1) { ["a"]=> int(123) }, $success == bool(true)


He intentado algo como eso

<?php /* valid json */ $json1 = json_encode([ ''foo'' => ''bar'', ''bar'', ''foo2 '' => [ ''bar'' => ''foo'', ''try''=> 32, ''foo'', ''bar'', [[[[[[]]]]]] ], ''foobar''=>[ ''foo''=>''bar'', ''bar''=>''foo'' ] ]); $json2 = json_encode([ ''foo'' => ''bar'', ''bar'', ''foo2 '' => [ ''bar'' => ''foo'', ''try''=> 32, ''foo'', ''bar'', [[[[[[]]]]]] ], ''foobar''=>[ ''foo''=>''bar'', ''bar''=>''foo'' ] ]) . '';''; // << invalid json $mt = microtime(1); for($i=0;$i<1000000;$i++){ check1($json1); check1($json2); } echo "PROCESS TOOK: " . (microtime(1) - $mt) . " seconds/n"; $mt = microtime(1); for($i=0;$i<1000000;$i++){ check2($json1); check2($json2); } echo "PROCESS TOOK: " . (microtime(1) - $mt) . " seconds/n"; function check1($json){ return preg_match(''/(?(DEFINE)(?<number>-?(?=[1-9]|0(?!/d))/d+(/./d+)?([eE][+-]?/d+)?)(?<boolean>true|false|null)(?<string>"([^"////]*|////["////bfnrt//]|////u[0-9a-f]{4})*")(?<array>/[(?:(?&json)(?:,(?&json))*)?/s*/])(?<pair>/s*(?&string)/s*:(?&json))(?<object>/{(?:(?&pair)(?:,(?&pair))*)?/s*/})(?<json>/s*(?:(?&number)|(?&boolean)|(?&string)|(?&array)|(?&object))/s*))/A(?&json)/Z/six'', $json); } function check2($json){ json_decode($json); return (json_last_error() === JSON_ERROR_NONE); }

salida

PROCESS TOOK: 7.5640170574188 seconds PROCESS TOOK: 4.4907619953156 seconds

hay ~ 3 segundos de diferencia entre la función de expresión regular y la función nativa json_decode, pero ocurre después de 1 millón de veces de repetición, por lo que no es demasiado breve de todos modos

Edición: después de algunos pensamientos prefiero esto;

if(checkjson($json)){ echo "this is json :3/n"; var_dump($json); } else { die(''omg this is not json!!!''); } function checkjson(&$json){ $json = json_decode($json); return (json_last_error() === JSON_ERROR_NONE); }


He intentado algunas de esas soluciones, pero nada estaba funcionando para mí. Intento esta cosa simple:

$isJson = json_decode($myJSON); if ($isJson instanceof /stdClass || is_array($isJson)) { echo("it''s JSON confirmed"); } else { echo("nope"); }

Creo que es una buena solución ya que la decodificación JSON sin el segundo parámetro da un objeto.

EDITAR: Si sabe cuál será la entrada, puede adaptar este código a sus necesidades. En mi caso, sé que tengo un Json que comienza por "{", así que no necesito comprobar si es una matriz.


La forma más rápida de decodificar un posible objeto JSON a un objeto / matriz PHP:

/** * If $value is a JSON encoded object or array it will be decoded * and returned. * If $value is not JSON format, then it will be returned unmodified. */ function get_data( $value ) { if ( ! is_string( $value ) ) { return $value; } if ( strlen( $value ) < 2 ) { return $value; } if ( ''{'' != $value[0] && ''['' != $value[0] ) { return $value; } $json_data = json_decode( $value ); if ( ! $json_data ) { return $value; } return $json_data; }


La forma más sencilla y rápida que utilizo es seguirla;

$json_array = json_decode( $raw_json , true ); if( $json_array == NULL ) //check if it was invalid json string die (''Invalid''); // Invalid JSON error // you can execute some else condition over here in case of valid JSON

Se debe a que json_decode() devuelve NULL si la cadena ingresada no es json o no es válida.


Función simple para validar JSON

Si tiene que validar su JSON en varios lugares, siempre puede usar la siguiente función.

function is_valid_json( $raw_json ){ return ( json_decode( $raw_json , true ) == NULL ) ? false : true ; // Yes! thats it. }

En la función anterior, obtendrá true a cambio si es un JSON válido.


Necesitamos verificar si la cadena pasada no es numérica porque en este caso json_decode no genera ningún error.

function isJson($str) { $result = false; if (!preg_match("/^/d+$/", trim($str))) { json_decode($str); $result = (json_last_error() == JSON_ERROR_NONE); } return $result; }


No sé sobre el rendimiento o la elegancia de mi solución, pero es lo que estoy usando:

if (preg_match(''/^[/[/{]/"/'', $string)) { $aJson = json_decode($string, true); if (!is_null($aJson)) { ... do stuff here ... } }

Ya que todas mis cadenas codificadas en JSON comienzan con {"es suficiente probar esto con un RegEx. No soy del todo fluido con RegEx, así que podría haber una mejor manera de hacerlo. También: strpos() podría ser más rápido.

Solo trato de ceder en mi valor de tuppence.

PS Just actualizó la cadena RegEx a /^[/[/{]/"/ para encontrar también cadenas de matriz JSON. Por lo tanto, ahora busca [" o {"al principio de la cadena.


Otra forma sencilla

function is_json($str) { return is_array(json_decode($str,true)); }


Todo lo que necesitas hacer es esto ...

if (is_object(json_decode($MyJSONArray))) { ... do something ... }

Esta solicitud no requiere una función separada incluso. Solo envuelve is_object alrededor de json_decode y sigue adelante. Parece que esta solución tiene gente que piensa demasiado en ella.


Un método fácil es verificar el resultado de json.

$result = @json_decode($json,true); if (is_array($result)) { echo ''JSON is valid''; }else{ echo ''JSON is not valid''; }


Una simple modificación de la respuesta de henrik para tocar las posibilidades más necesarias.

(incluyendo "{} y []")

function isValidJson($string) { json_decode($string); if(json_last_error() == JSON_ERROR_NONE) { if( $string[0] == "{" || $string[0] == "[" ) { $first = $string [0]; if( substr($string, -1) == "}" || substr($string, -1) == "]" ) { $last = substr($string, -1); if($first == "{" && $last == "}"){ return true; } if($first == "[" && $last == "]"){ return true; } return false; } return false; } return false; } return false; }


Uno debería considerar algunos métodos de alineación de json más complicados. Prefiero usar https://github.com/Seldaek/jsonlint que no devuelve las falsas posividades mencionadas en las alternativas anteriores.


Usar json_decode para "sondear" podría no ser la manera más rápida. Si se trata de una estructura profundamente anidada, la creación de una gran cantidad de objetos de arreglos para simplemente desecharlos es una pérdida de tiempo y memoria.

Por lo tanto, podría ser más rápido usar preg_match y la RFC4627 regular RFC4627 para garantizar también la validez :

// in JS: var my_JSON_object = !(/[^,:{}/[/]0-9./-+Eaeflnr-u /n/r/t]/.test( text.replace(/"(//.|[^"//])*"/g, '''')));

Lo mismo en PHP:

return !preg_match(''/[^,:{}//[//]0-9.//-+Eaeflnr-u //n//r//t]/'', preg_replace(''/"(//.|[^"////])*"/'', '''', $json_string));

Sin embargo, no es suficiente para los entusiastas del rendimiento como para preocuparse por los puntos de referencia.


en GuzzleHttp :

/** * Wrapper for json_decode that throws when an error occurs. * * @param string $json JSON data to parse * @param bool $assoc When true, returned objects will be converted * into associative arrays. * @param int $depth User specified recursion depth. * @param int $options Bitmask of JSON decode options. * * @return mixed * @throws /InvalidArgumentException if the JSON cannot be decoded. * @link http://www.php.net/manual/en/function.json-decode.php */ function json_decode($json, $assoc = false, $depth = 512, $options = 0) { $data = /json_decode($json, $assoc, $depth, $options); if (JSON_ERROR_NONE !== json_last_error()) { throw new /InvalidArgumentException( ''json_decode error: '' . json_last_error_msg()); } return $data; } /** * Wrapper for JSON encoding that throws when an error occurs. * * @param mixed $value The value being encoded * @param int $options JSON encode option bitmask * @param int $depth Set the maximum depth. Must be greater than zero. * * @return string * @throws /InvalidArgumentException if the JSON cannot be encoded. * @link http://www.php.net/manual/en/function.json-encode.php */ function json_encode($value, $options = 0, $depth = 512) { $json = /json_encode($value, $options, $depth); if (JSON_ERROR_NONE !== json_last_error()) { throw new /InvalidArgumentException( ''json_encode error: '' . json_last_error_msg()); } return $json; }


Debería ser algo como esto:

function isJson($string) { // 1. Speed up the checking & prevent exception throw when non string is passed if (is_numeric($string) || !is_string($string) || !$string) { return false; } $cleaned_str = trim($string); if (!$cleaned_str || !in_array($cleaned_str[0], [''{'', ''[''])) { return false; } // 2. Actual checking $str = json_decode($string); return (json_last_error() == JSON_ERROR_NONE) && $str && $str != $string; }

Prueba de unidad

public function testIsJson() { $non_json_values = [ "12", 0, 1, 12, -1, '''', null, 0.1, ''.'', "''''", true, false, [], ''""'', ''[]'', '' {'', '' ['', ]; $json_values = [ ''{}'', ''{"foo": "bar"}'', ''[{}]'', '' {}'', '' {} '' ]; foreach ($non_json_values as $non_json_value) { $is_json = isJson($non_json_value); $this->assertFalse($is_json); } foreach ($json_values as $json_value) { $is_json = isJson($json_value); $this->assertTrue($is_json); } }


La función personalizada

function custom_json_decode(&$contents=NULL, $normalize_contents=true, $force_array=true){ //---------------decode contents--------------------- $decoded_contents=NULL; if(is_string($contents)){ $decoded_contents=json_decode($contents,$force_array); } //---------------normalize contents--------------------- if($normalize_contents===true){ if(is_string($decoded_contents)){ if($decoded_contents===''NULL''||$decoded_contents===''null''){ $contents=NULL; } elseif($decoded_contents===''FALSE''||$decoded_contents===''false''){ $contents=false; } } elseif(!is_null($decoded_contents)){ $contents=$decoded_contents; } } else{ //---------------validation contents--------------------- $contents=$decoded_contents; } return $contents; }

Casos

$none_json_str=''hello''; //------------decoding a none json str--------------- $contents=custom_json_decode($none_json_str); // returns ''hello'' //------------checking a none json str--------------- custom_json_decode($none_json_str,false); $valid_json=false; if(!is_null($none_json_str)){ $valid_json=true; }

Recursos

https://gist.github.com/rafasashi/93d06bae83cc1a1f440b


function isJson($string) { json_decode($string); return (json_last_error() == JSON_ERROR_NONE); }


function is_json($input) { $input = trim($input); if (substr($input,0,1)!=''{'' OR substr($input,-1,1)!=''}'') return false; return is_array(@json_decode($input, true)); }



if(!empty(json_decode($data))) { echo "real json"; }