我需要一个非常非常快的方法来检查字符串是否为JSON。我觉得这不是最好的方式:

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

有没有表演爱好者想改进这种方法?


当前回答

应该是这样的:

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

单元测试

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

其他回答

我使用的最简单和最快的方法是跟随;

$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。

这样就可以了:

function isJson($string) {
    $decoded = json_decode($string); // decode our JSON string
    if ( !is_object($decoded) && !is_array($decoded) ) {
        /*
        If our string doesn't produce an object or array
        it's invalid, so we should return false
        */
        return false;
    }
    /*
    If the following line resolves to true, then there was
    no error and our JSON is valid, so we return true.
    Otherwise it isn't, so we return false.
    */
    return (json_last_error() == JSON_ERROR_NONE);
}

if ( isJson($someJsonString) ) {
    echo "valid JSON";
} else {
    echo "not valid JSON";
}

如其他答案所示,json_last_error()返回来自上一次json_decode()的任何错误。然而,在一些边缘用例中,仅使用这个功能还不够全面。例如,如果你json_decode()一个整数(例如:123),或者一个没有空格或其他字符的数字字符串(例如:“123”),json_last_error()函数将不会捕获错误。

为了解决这个问题,我添加了一个额外的步骤,以确保json_decode()的结果是一个对象或数组。如果不是,则返回false。

要查看具体操作,请查看以下两个示例:

只使用json_last_error()检查 首先检查对象/数组

嗨,这是我的库中的一个小片段,在第一个条件下,我只是检查数据是否为json,然后返回它,如果正确解码,请注意substr的使用性能(我还没有看到任何json文件不以{或[开始

$input=trim($input);
if ((substr($input, 0, 1) == '{' && substr($input, -1) == '}') or (substr($input, 0, 1) == '[' && substr($input, -1) == ']')) {
    $output = json_decode($input, 1);
    if (in_array(gettype($output),['object','array'])) {
        #then it's definitely JSON
    }
}

另一种简单的方法

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

我知道这个问题已经过时了,但是我想通知大家,json_validate()函数的RFC已经实现,并且将成为php 8.3的一部分

这种方法将是实现问题要求的最快和更有效的方法。

Github -实现代码

RFC - json_validate()