477

文字列が JSON かどうかを非常に高速に確認する方法が必要です。これは最善の方法ではないように感じます:

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

この方法を改善したいパフォーマンス愛好家はいますか?

4

32 に答える 32

697
function isJson($string) {
   json_decode($string);
   return json_last_error() === JSON_ERROR_NONE;
}
于 2011-05-18T08:20:35.047 に答える
204

質問への回答

この関数json_last_errorは、JSON のエンコードおよびデコード中に発生した最後のエラーを返します。したがって、有効な JSON を確認する最速の方法は次のとおりです。

// 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
}

json_last_errorPHP >= 5.3.0 でのみサポートされていることに注意してください。

正確なエラーを確認するための完全なプログラム

開発中に正確なエラーを知ることは常に良いことです。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;
}

有効な JSON INPUT を使用したテスト

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

有効な出力

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

    [1] => stdClass Object
        (
            [user_id] => 14
            [username] => over
        )
)

無効な JSON を使用したテスト

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

無効な出力

Syntax error, malformed JSON.

(PHP >= 5.2 && PHP < 5.3.0) に関する特別な注意事項

は PHP 5.2 ではサポートされていないためjson_last_error、エンコードまたはデコードが boolean を返すかどうかを確認できますFALSE。ここに例があります

// decode the JSON data
$result = json_decode($json);
if ($result === FALSE) {
    // JSON is invalid
}
于 2013-03-04T10:04:22.027 に答える
95

あなたが本当にする必要があるのはこれだけです...

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

このリクエストは別の機能さえも必要としません。is_object を json_decode にラップして先に進みます。このソリューションには、人々があまりにも多くのことを考えているようです。

于 2012-09-07T04:41:59.617 に答える
76

「プローブ」を使用json_decodeするのは、実際には最速の方法ではない場合があります。深くネストされた構造の場合、配列の多くのオブジェクトをインスタンス化してそれらを破棄するのは、メモリと時間の無駄です。

したがって、使用する方が高速preg_matchで、RFC4627正規表現を使用して有効性を確保することもできます。

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

PHPでも同じ:

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

ただし、ここでベンチマークを気にするほどのパフォーマンス愛好家ではありません。

于 2011-05-18T08:27:25.393 に答える
27

私が使用する最も簡単で最速の方法は次のとおりです。

$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

これは 、入力された文字列が json でない場合、または無効な json の場合、json_decode()が NULL を返すためです。


JSON を検証する単純な関数

JSON を複数の場所で検証する必要がある場合は、いつでも次の関数を使用できます。

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

上記の関数では、有効な JSON である場合に true が返されます。

于 2014-08-28T04:01:23.873 に答える
22
function is_json($str){ 
    return json_decode($str) != null;
}

http://tr.php.net/manual/en/function.json-decode.php無効なエンコーディングが検出された場合の戻り値は null です。

于 2011-05-18T08:21:11.893 に答える
10

簡単な方法は、jsonの結果を確認することです..

$result = @json_decode($json,true);
    if (is_array($result)) {
        echo 'JSON is valid';
    }else{
        echo 'JSON is not valid';
    }
于 2016-09-29T09:34:06.227 に答える
6

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;
}
于 2016-12-20T13:27:07.537 に答える
5

渡された文字列が数値でないかどうかを確認する必要があります。この場合、json_decode はエラーを発生させないためです。

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

    return $result;
}
于 2016-05-11T07:02:07.133 に答える
5

以前は null 値をチェックしていましたが、実際には間違っていました。

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

上記のコードは、文字列で正常に機能します。ただし、番号を入力するとすぐに壊れます。たとえば。

    $data = "1213145";
    $r_data = json_decode($data);

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

それを修正するために私がしたことは非常に簡単でした。

    $data = "ahad";
    $r_data = json_decode($data);

    if(($r_data != $data) && $r_data)
        print "Json success";
    else
        print "Json error";
于 2014-06-27T02:10:11.440 に答える
4

別の簡単な方法

function is_json($str)
{
    return is_array(json_decode($str,true));
}
于 2014-02-08T06:09:50.257 に答える
2

私のソリューションのパフォーマンスやエレガンスについてはわかりませんが、それは私が使用しているものです:

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

すべての JSON エンコード文字列は {" で始まるため、これをRegEx でテストするだけで十分です。

私のタペンスの価値を与えようとしているだけです。

PS RegEx 文字列を更新して、/^[\[\{]\"/JSON 配列文字列も検索できるようにしました。そのため、文字列の先頭で [" または {" を探します。

于 2013-02-14T09:02:45.303 に答える
-1

成功時にデコードされたデータが必要な場合は、PHP 5.2 との互換性のために新たに作成された関数:

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;
}

使用法:

$json_or_not = ...;

$data = try_json_decode( $json_or_not, $success );

if( $success )
     process_data( $data );
else what_the_hell_is_it( $data );

いくつかのテスト:

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)
于 2015-05-26T11:12:25.897 に答える
-1
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));
}
于 2015-07-11T19:54:06.283 に答える
-1

最も必要な可能性に触れるためのヘンリックの答えへの簡単な変更。

( " {} と [] " を含む )

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;

}
于 2017-06-22T07:22:58.523 に答える