Cách nhanh nhất để kiểm tra xem một chuỗi có phải là JSON trong PHP không?


385

Tôi cần một phương pháp thực sự rất nhanh để kiểm tra xem một chuỗi có phải là JSON hay không. Tôi cảm thấy như đây không phải là cách tốt nhất:

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

Bất kỳ người đam mê hiệu suất ngoài kia muốn cải thiện phương pháp này?


3
Chỉ xem xét sử dụng json_decodemột lần ... đồng thời, kiểm tra giá trị đầu vào và trả về của json_decode.

5
Vì vậy, cái nào là câu trả lời?
Farid Rn

8
Việc chuyển đổi ternary ở đây là dư thừa. Tuyên bố của bạn đã được đánh giá là một boolean.
Tôi vật lộn một con gấu một lần.


Chấp nhận câu trả lời của Lewis Donovan ... nó đang hoạt động tốt
Poonam Bhatt

Câu trả lời:


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

19
Hình như mọi người đều thích câu trả lời này. Bất kỳ lời giải thích tại sao?
Kirk Ouimet

8
Tôi tin rằng PHP 5.3> là cần thiết để sử dụng hàm json_last_error
Chris Harrison

97
Kiểm tra ký tự đầu tiên của chuỗi {, [hoặc ký hiệu đầu tiên của bất kỳ nghĩa đen nào khác có khả năng tăng tốc độ này lên rất nhiều khi nhiều chuỗi đến dự kiến ​​không phải là JSON.
Oleg V. Volkov

20
$ điện thoại = '021234567'; var_dump (isJson ($ phone)); Trả lại đúng không! nó sẽ trả về false.
vee

23
Coi chừng, hàm này sẽ trả về true cho bất kỳ số nào, cho dù bạn chỉ định nó là một chuỗi hay một số thực. 6.5 = true, '300' = true, 9 = truev.v ... Vì vậy, đây có thể là một giá trị JSON hợp lệ nhưng hàm có thể không hoạt động như bạn mong đợi, nếu bạn chỉ muốn kiểm tra các chuỗi JSON hợp lệ có {}hoặc [];
BadHorsie

156

Trả lời câu hỏi

Hàm json_last_errortrả về lỗi cuối cùng xảy ra trong quá trình mã hóa và giải mã JSON. Vì vậy, cách nhanh nhất để kiểm tra JSON hợp lệ là

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

Lưu ý rằng chỉ json_last_errorđược hỗ trợ trong PHP> = 5.3.0.

Chương trình đầy đủ để kiểm tra LRI chính xác

Luôn luôn là tốt để biết lỗi chính xác trong thời gian phát triển. Đây là chương trình đầy đủ để kiểm tra lỗi chính xác dựa trên các tài liệu 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;
}

Kiểm tra với JSON INPUT hợp lệ

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

ĐẦU RA hợp lệ

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

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

Kiểm tra với JSON không hợp lệ

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

ĐẦU RA không hợp lệ

Syntax error, malformed JSON.

Ghi chú thêm cho (PHP> = 5.2 && PHP <5.3.0)

json_last_errorkhông được hỗ trợ trong PHP 5.2, bạn có thể kiểm tra xem mã hóa hoặc giải mã có trả về boolean không FALSE. Đây là một ví dụ

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

Hy vọng điều này là hữu ích. Chúc mừng mã hóa!


Độ chính xác nhỏ: nếu json này hợp lệ nhưng mã được giải mã trước đó không hợp lệ, mã của bạn sẽ hoạt động chính xác, bởi vì: " Trả về lỗi cuối cùng (nếu có) xảy ra trong quá trình mã hóa / giải mã JSON cuối cùng . "
Bruno

Cảm ơn @Madan, xác minh "json_decode" đã giải quyết cho tôi rằng tôi đang chạy PHP 7.0.
Francis Coleues

Chắc chắn json_decode chỉ có thể trả về false cho sai theo nghĩa đen, vì vậy một kiểm tra ((strlen($json) === 5) && ($json !== 'false'))cũng nên được thực hiện để tránh cạnh đó?
MrMesees

@Bruno Nếu giải mã cuối cùng hoạt động mà không có lỗi thì json_last_errortrả về JSON_ERROR_NONE.
Andrea

80

Tất cả những gì bạn thực sự cần làm là ...

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

Yêu cầu này thậm chí không yêu cầu một chức năng riêng biệt. Chỉ cần bọc is_object xung quanh json_decode và di chuyển trên. Có vẻ như giải pháp này khiến mọi người đặt quá nhiều suy nghĩ vào nó.


1
@ RomanM.Kos Chỉ cần rõ ràng, nếu mảng là một mảng đơn giản, thì bạn cần sử dụng is_arraythêm vào is_object, nếu không, is_objectsẽ trả về false cho các mảng đơn giản được mã hóa dưới dạng JSON. Vì vậy, @ggutenberg là đúng trong trường hợp này. Truyền đối số thực để json_decodebuộc một đối tượng được trả về dưới dạng một mảng. Về lý thuyết, bạn luôn có thể buộc giải mã thành một mảng và chỉ cần kiểm tra is_array, nó sẽ hoạt động.
userabuser

@userabuser Nếu tôi json_encode($array)cho mảng PHP đơn giản, thì json_decode($str)tôi sẽ nhận được đối tượng, nhưng không phải là mảng. json_decode($str, true)lực lượng để chuyển đổi thành mảng. Tại sao chuỗi phức tạp trong mã của bạn? Kiểm tra is_array(json_decode($str, true))và một thời gian sau khi bạn đọc nó, bạn sẽ hiểu rằng giải mã phải chỉ là một mảng. Khó đoán hơn nhiều is_object(json_decode($MyJSONArray))"Ồ, ở đây tôi đang kiểm tra giải mã có phải là một mảng hay không?"
Roman M. Koss

@ RomanM.Kos Không, điều đó không đúng, codepad.viper-7.com/OFrtsq - như tôi đã nói, bạn luôn có thể buộc json_decodetrả về một mảng để giúp bạn kiểm tra đối tượng và mảng, nhưng nếu bạn KHÔNG VÀ bạn json_decodethì sao là một mảng đơn giản để bắt đầu, bạn sẽ nhận được một mảng khi trả về giải mã, không phải là một đối tượng. Bạn phải sử dụng JSON_FORCE_OBJECTnếu bạn muốn luôn luôn buộc một đối tượng mã hóa NẾU truyền một mảng đơn giản.
dùng

11
Downvote cho biết : This request does not require a separate function even. Nói đúng ra, không có giải pháp nào đòi hỏi một chức năng riêng. Điểm của hàm không phải là làm cho nhiều dòng mã trông giống như một dòng mã. Mục đích của chức năng là làm cho tiêu chuẩn quy trình kiểm tra JSON ở mọi nơi trong ứng dụng của bạn, để các lập trình viên khác nhau (hoặc cùng một lập trình viên theo thời gian) không sử dụng các quy trình kiểm tra khác nhau ở các giai đoạn khác nhau trong luồng chương trình.
cartb Beforehorse

71

Sử dụng json_decodeđể "thăm dò" nó có thể không thực sự là cách nhanh nhất. Nếu đó là một cấu trúc lồng nhau sâu sắc, thì việc tạo ra rất nhiều đối tượng của mảng để chỉ cần ném chúng đi là một sự lãng phí bộ nhớ và thời gian.

Vì vậy, nó có thể được sử dụng nhanh hơn preg_matchregex RFC4627 để đảm bảo tính hợp lệ :

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

Tương tự trong PHP:

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

Tuy nhiên, không đủ người đam mê hiệu suất để bận tâm với điểm chuẩn ở đây.


11
Hoàn thành regex đệ quy để xác minh JSON tại đây: stackoverflow.com/questions/2583472/regex-to-validate-json/ mẹo - Nhưng hóa ra PHP json_decodeluôn nhanh hơn regex PCRE. (Mặc dù nó không được tối ưu hóa lắm, nhưng không có thử nghiệm tổng hợp nào được tìm thấy và có thể hoạt động khác đi trong Perl ..)
mario

3
@vee Vâng, cảm ơn bạn đã lưu ý. Nhưng hãy giữ nó ở đây [không chính xác], vì vậy không ai thực sự sử dụng nó trong sản xuất.
mario

1
@cartb Beforehorse Được rồi, cảm ơn. Tôi đã sửa lỗi thoát tuyệt vời cho bối cảnh chuỗi trích dẫn PHP sau đó.
mario

1
@cartb Beforehorse Nó không. Chủ yếu là trang trí. Đó chỉ là dấu gạch chéo ngược theo nghĩa đen mà thực sự đòi hỏi phải thoát gấp đôi. Vì \r \n \tnó chỉ có ý nghĩa nên PHP không nội suy chúng, nhưng hãy để PCRE diễn giải chúng (chỉ được yêu cầu cho /xchế độ). Các sự kiện khác không thực sự cần nó; nhưng vẫn "dấu gạch chéo tự thoát" trong tất cả các bối cảnh chuỗi PHP. Vì vậy, người ta có thể xem xét nó chính xác hơn.
mario

4
@mario Được rồi, tôi hiểu rồi. Về cơ bản, PHP thoát khỏi dấu gạch chéo ngược trước khi công cụ reg-exp được nhìn thấy nó. Theo như công cụ reg-exp có liên quan, có một nửa số dấu gạch chéo ngược trong chuỗi như những gì con người chúng ta thấy. "Giống như reg-exp chưa đủ phức tạp"
cartb Beforehorse

39

Điều này sẽ trả về true nếu chuỗi của bạn đại diện cho một mảng hoặc đối tượng json :

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

Nó từ chối các chuỗi json chỉ chứa một số, chuỗi hoặc boolean, mặc dù các chuỗi đó là json hợp lệ về mặt kỹ thuật.

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)

Đó là con đường ngắn nhất mà tôi có thể nghĩ ra.


Thay vì var_dump, bạn có thể đặt cái này trong trường hợp thử nghiệm PHPUnit. Nếu không, tôi vừa ngạc nhiên vừa vui khi biết điều đó là sự thật.
MrMesees

3
Tại sao mọi người khác có câu trả lời dài dòng như vậy khi điều này làm việc tuyệt vời? Cảm ơn.
chập chững

1
Đơn giản, đáng yêu! Không kiểm tra "cách nhanh nhất" hoặc hiệu suất khôn ngoan nhưng điều này chắc chắn bao gồm tất cả các trường hợp tôi từng kiểm tra. Đây là một ví dụ kinh điển cho câu tục ngữ khét tiếng "Đừng dùng búa tạ để bẻ khóa" . Từ quan điểm lập trình viên, tốt hơn hết là giữ mã đơn giản, ngắn gọn và dễ hiểu, hiệu năng so với đơn giản là một cuộc tranh luận khác ngoài phạm vi cho chủ đề này.
Fr0zenFyr

Đây là một chút logic, nhưng cũng lưu ý rằng nó trả về false cho các mảng trống. Ví dụ : var_dump(isJson('[]')); // bool(false). Theo tài liệu về booleans, điều này là do PHP đánh giá các mảng có các phần tử bằng 0 là sai. Đây là một sửa đổi nhỏ để điều chỉnh tuyên bố trở lại; nó thực hiện một so sánh giống hệt nhau trên đầu ra được giải mã xử lý trường hợp này:return $json !== false && $str != $json;
j13k

@ j13k So sánh giống hệt nhau đánh giá isJson('hello')là đúng, không hợp lệ json. So sánh lỏng lẻo được chọn vào mục đích ở đây. Tôi không có giải pháp nhanh cho tình huống mảng / đối tượng trống, ngoại trừ xấu xíreturn $json == '[]' || ...
Cyril

21

Cách đơn giản nhất và nhanh nhất mà tôi sử dụng là theo sau;

$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

Đó là bởi vì json_decode () trả về NULL nếu chuỗi đã nhập không phải là json hoặc json không hợp lệ.


Hàm đơn giản để xác thực JSON

Nếu bạn phải xác thực JSON của mình ở nhiều nơi, bạn luôn có thể sử dụng hàm sau.

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

Trong hàm trên, bạn sẽ nhận được true nếu đó là JSON hợp lệ.


3
json_decode('null') == NULLnulllà một giá trị JSON hợp lệ.
zzzzBov

Tôi đã kiểm tra xem 'null' có hợp lệ json tại json.parser.online không nhưng có vẻ như nó không hợp lệ. Và json_decode () là hàm lõi php để xác thực json vì vậy tôi nghi ngờ sẽ nhận được một số kết quả sai trong đầu ra của chúng tôi.
Mohammad Mursaleen

Thay vì tin tưởng một số trang web chưa được xác minh, hãy xem xét tư vấn thông số kỹ thuật, điều này không đồng ý (trg 2) . Ngoài ra, hãy thử JSON.parse('null')trong giao diện điều khiển dev của bạn.
zzzzBov

19
function is_json($str){ 
    return json_decode($str) != null;
}

http://tr.php.net/manual/en/feft.json-decode.php giá trị trả về là null khi phát hiện mã hóa không hợp lệ.


4
Nó cũng sẽ trả về null một cách không chính xác cho "null" (không phải là JSON hợp lệ, nhưng có thể hoàn toàn "hợp lệ" với json_decode nếu không). Đi hình.

Tôi nghĩ rằng điều này có thể là: json_decode($str)!=null;hoặc nếu không thì hàm nên được gọi is_not_json.
Yoshi

Hàm đó sẽ được đổi tên tốt hơn "là một cái gì đó khác với JSON"!
cô đơn

2
@ user166390, json_decode('null')là JSON hợp lệ theo thông số kỹ thuật và sẽ trả về giá trị của null.
zzzzBov

Cũng xin lưu ý rằng với phương pháp này is_json('false')is_json('[]')sẽ trả về falselà loại không được kiểm tra. Tôi nghĩ rằng phương pháp này nên trở lại $str === null || json_decode($str) !== null.
Antoine Pinsard

11

Bạn phải xác thực đầu vào của mình để đảm bảo chuỗi bạn truyền không trống và trên thực tế, đó là một chuỗi. Một chuỗi rỗng không phải là JSON hợp lệ.

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

Tôi nghĩ trong PHP điều quan trọng hơn là xác định xem đối tượng JSON dữ liệu hay không, bởi vì để sử dụng dữ liệu bạn sẽ cần phải gọi json_encode()hoặc json_decode(). Tôi khuyên bạn nên từ chối các đối tượng JSON trống để bạn không cần thiết phải chạy mã hóa và giải mã dữ liệu trống.

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

+1 để thực sự suy nghĩ về vấn đề trong bối cảnh thực tế.
cartb Beforehorse

Nhưng '0'json không hợp lệ ... tại sao tôi phải cảnh giác? @Kzqai
đầy đủ

11

Điều này sẽ làm điều đó:

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

Như được hiển thị trong các câu trả lời khác, json_last_error()trả về bất kỳ lỗi nào từ json_decode () cuối cùng của chúng tôi. Tuy nhiên, có một số trường hợp sử dụng cạnh mà chức năng này không đủ toàn diện. Ví dụ: nếu bạn json_decode()là một số nguyên (ví dụ 123:) hoặc một chuỗi số không có khoảng trắng hoặc ký tự khác (ví dụ "123":), json_last_error()hàm sẽ không bắt lỗi.

Để chống lại điều này, tôi đã thêm một bước bổ sung để đảm bảo kết quả của chúng ta json_decode()là một đối tượng hoặc một mảng. Nếu không, chúng tôi sẽ quay lại false.

Để thấy điều này trong thực tế, kiểm tra hai ví dụ sau:


"hello"là một JSON hợp lệ và nó không phải là một đối tượng cũng không phải là một mảng, json_last_error()là đủ
JoniJnm

1
json_last_error()trả về mã lỗi 4khi bạn json_decode()chuỗi "hello". Ví dụ ở đây: 3v4l.org/lSsEo
Lewis Donovan

Mã của bạn sai, hellokhông phải là JSON hợp lệ, nhưng "hello"3v4l.org/OEJrQ
JoniJnm

9

Phương pháp dễ dàng là kiểm tra kết quả json ..

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

6

trong GuheadsHttp :

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

5

Trước đó tôi chỉ kiểm tra một giá trị null, thực sự đã sai.

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

Đoạn mã trên hoạt động tốt với chuỗi. Tuy nhiên ngay sau khi tôi cung cấp số, nó sẽ chia tay. Ví dụ.

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

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

Để sửa nó, những gì tôi đã làm rất đơn giản.

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

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

Giải pháp tốt đẹp. Xử lý vấn đề đánh máy rất tốt!
Chaoix

5
//Tested thoroughly, Should do the job:
public static function is_json(string $json):bool
{
    json_decode($json);
    if (json_last_error() === JSON_ERROR_NONE) {
        return true;
    }
    return false;
}

4

Một cách đơn giản khác

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

1
Điều này không đúng. Bất kỳ loại PHP nào cũng có thể được mã hóa thành JSON như các đối tượng, chuỗi, v.v. và hàm json_decode dự kiến ​​sẽ trả về chúng. Điều này chỉ đúng nếu bạn luôn giải mã mảng và không có loại biến nào khác.
Chaoix

@Chaoix bằng cách sử dụng json_decode($str,true)làm cho nó chuyển đổi các đối tượng thành mảng để nó sẽ vượt qua kiểm tra is_array. Bạn sửa về chuỗi, số nguyên, vv mặc dù.
Paul Phillips

Tôi hiểu ý của bạn về tham số thứ hai trên json_encode. Tôi vẫn nghĩ rằng giải pháp của @Ahad Ali là một giải pháp tốt hơn nhiều về cách gõ và chỉ thực hiện một json_decode một lần trong các thuật toán của bạn.
Chaoix

4

Chúng ta cần kiểm tra xem chuỗi đã qua có phải là số không vì trong trường hợp này json_decode không phát sinh lỗi.

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

    return $result;
}

4

Tôi tìm thấy câu hỏi này sau khi bắt gặp một cái gì đó tương tự trong công việc của tôi, ngày hôm qua. Giải pháp cuối cùng của tôi là kết hợp một số cách tiếp cận ở trên:

function is_JSON($string) {

  $String_Is_JSON = (is_null(json_decode($string, TRUE))) ? FALSE : TRUE;

  return $String_Is_JSON;
}

3

Tôi đã thử một số giải pháp đó nhưng không có gì hiệu quả với tôi. Tôi thử điều đơn giản này:

$isJson = json_decode($myJSON);

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

Tôi nghĩ rằng đó là một solutiuon tốt vì giải mã JSON mà không có tham số thứ hai cho một đối tượng.

EDIT: Nếu bạn biết cái gì sẽ là đầu vào, bạn có thể điều chỉnh mã này theo nhu cầu của mình. Trong trường hợp của tôi, tôi biết rằng tôi có một Json bắt đầu bằng "{", vì vậy tôi không cần kiểm tra xem đó có phải là một mảng không.


JSON của bạn có khả năng chỉ là một mảng, trong trường hợp đó, nó sẽ là một mảng thay vì stdClass $ foo = "[1, 1, 2, 3]"; var_dump (json_decode ($ foo)); => mảng (4) {[0] => int (1) [1] => int (1) [2] => int (2) [3] => int (3)}
Misha Nasledov

3

Sử dụng PHPBench với lớp sau, đã đạt được kết quả dưới đây:

<?php

declare(strict_types=1);

/**
 * Benchmark doctrine persistent collection count method vs sizeof toArray
 * Revs is the number of times you want the benchmark to run
 * @Revs(1000)
 * @Iterations(100)
 */
class BenchmarkJson
{
    public function benchCatchValid(): bool
    {
        $validJson = '{"validJson":true}';
        try {
            json_decode($validJson, true, 512, JSON_THROW_ON_ERROR);
            return true;
        } catch(\JsonException $exception) {}
        return false;
    }

    public function benchCatchInvalid(): bool
    {
        $invalidJson = '{"invalidJson"';
        try {
            json_decode($invalidJson, true, 512, JSON_THROW_ON_ERROR);
            return true;
        } catch(\JsonException $exception) {}
        return false;
    }

    public function benchLastErrorValid(): bool
    {
        $validJson = '{"validJson":true}';
        json_decode($validJson, true);
        return (json_last_error() === JSON_ERROR_NONE);
    }

    public function benchLastErrorInvalid(): bool
    {
        $invalidJson = '{"invalidJson"';
        json_decode($invalidJson, true);
        return (json_last_error() === JSON_ERROR_NONE);
    }

    public function benchNullValid(): bool
    {
        $validJson = '{"validJson":true}';
        return (json_decode($validJson, true) !== null);
    }

    public function benchNullInvalid(): bool
    {
        $invalidJson = '{"invalidJson"';
        return (json_decode($invalidJson, true) !== null);
    }
}
6 subjects, 600 iterations, 6,000 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 0.714 [1.203 1.175] 1.073 s)
T: 721.504μs μSD/r 0.089μs μRSD/r: 7.270%
suite: 1343ab9a3590de6065bc0bc6eeb344c9f6eba642, date: 2020-01-21, stime: 12:50:14
+---------------+-----------------------+-----+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+
| benchmark     | subject               | set | revs | its | mem_peak   | best    | mean    | mode    | worst   | stdev   | rstdev | diff  |
+---------------+-----------------------+-----+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+
| BenchmarkJson | benchCatchValid       | 0   | 1000 | 100 | 2,980,168b | 0.954μs | 1.032μs | 1.016μs | 1.428μs | 0.062μs | 6.04%  | 1.33x |
| BenchmarkJson | benchCatchInvalid     | 0   | 1000 | 100 | 2,980,184b | 2.033μs | 2.228μs | 2.166μs | 3.001μs | 0.168μs | 7.55%  | 2.88x |
| BenchmarkJson | benchLastErrorValid   | 0   | 1000 | 100 | 2,980,184b | 1.076μs | 1.195μs | 1.169μs | 1.616μs | 0.083μs | 6.97%  | 1.54x |
| BenchmarkJson | benchLastErrorInvalid | 0   | 1000 | 100 | 2,980,184b | 0.785μs | 0.861μs | 0.863μs | 1.132μs | 0.056μs | 6.54%  | 1.11x |
| BenchmarkJson | benchNullValid        | 0   | 1000 | 100 | 2,980,168b | 0.985μs | 1.124μs | 1.077μs | 1.731μs | 0.114μs | 10.15% | 1.45x |
| BenchmarkJson | benchNullInvalid      | 0   | 1000 | 100 | 2,980,184b | 0.714μs | 0.775μs | 0.759μs | 1.073μs | 0.049μs | 6.36%  | 1.00x |
+---------------+-----------------------+-----+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+

Kết luận: Cách nhanh nhất để kiểm tra xem json có hợp lệ hay không là trả về json_decode($json, true) !== null).


rất đẹp :) tôi ngưỡng mộ bạn
Mahdi

2

Tôi không biết về hiệu suất hoặc sự thanh lịch của giải pháp của mình, nhưng đó là những gì tôi đang sử dụng:

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

Vì tất cả các chuỗi được mã hóa JSON của tôi bắt đầu bằng {", nó đủ để kiểm tra điều này với RegEx. Tôi không rành về RegEx, vì vậy có thể có cách tốt hơn để làm điều này. Ngoài ra: strpose () có thể nhanh hơn.

Chỉ cần cố gắng để đưa ra giá trị tuppence của tôi.

PS Chỉ cần cập nhật chuỗi RegEx /^[\[\{]\"/để tìm chuỗi chuỗi JSON. Vì vậy, bây giờ nó tìm kiếm ["hoặc {" ở đầu chuỗi.


2

Nên là một cái gì đó như thế này:

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

Đơn vị

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

Tôi thích rằng bạn đang kiểm tra nếu đó là một chuỗi. Kết hợp tốt với giải pháp đầu tiên để tránh ErrorExceptionnếu chuỗi là mảng hoặc đối tượng.
sykez

1

Mở rộng về câu trả lời này Làm thế nào về những điều sau đây:

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

1
Không nên thực hiện kiểm tra chuỗi con trước khi thực hiện giải mã để tiết kiệm thời gian nếu phát hiện thấy lỗi trong kiểm tra đó? Tôi sẽ tưởng tượng rằng 4 kiểm tra chuỗi con sẽ nhanh hơn json_decode, nhưng nếu ai đó có thể hỗ trợ tôi với giả định này, tôi sẽ đánh giá cao bất kỳ suy nghĩ nào về việc này.
Đánh dấu

Đó là một cuộc tranh cãi về giá vé. Tôi không biết thời gian xử lý liên quan, nhưng nếu nó nhanh hơn thì có.
Thứ bảy

1

Xin chào, đây là một đoạn nhỏ từ thư viện của tôi, trong điều kiện đầu tiên này, tôi chỉ kiểm tra xem dữ liệu có phải là json không, sau đó trả lại nếu được giải mã chính xác, xin lưu ý cách sử dụng chất nền cho hiệu suất (Tôi chưa thấy tệp json nào không bắt đầu bởi {hoặc [

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

Đã có 34 câu trả lời được đăng cho câu hỏi này, nhiều câu hỏi cũng đăng ký với niềm tin (nhầm lẫn) rằng JSON phải đại diện cho một mảng hoặc một đối tượng. Là câu trả lời này làm bất cứ điều gì khác với 3 tá câu trả lời khác?
miken32

1

Một đề nghị khác từ tôi :)

function isJson(string $string) {
  return ($result = json_decode($string, true)) ? $result : $string;
}

0

Chức năng tùy chỉnh

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

Các trường hợp

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

}

Tài nguyên

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


0

Hàm được tạo mới để tương thích PHP 5.2, nếu bạn cần dữ liệu được giải mã thành công:

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

Sử dụng:

$json_or_not = ...;

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

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

Một số xét nghiệm:

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)

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

2
@ sử dụng để gỡ lỗi (ẩn một lỗi) nhưng nó hoàn toàn không được khuyến nghị
vào

0

Một sửa đổi đơn giản cho câu trả lời của henrik để chạm vào hầu hết các khả năng cần thiết.

(bao gồm "{} và []")

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;

}

0

Cách nhanh nhất để có thể giải mã một đối tượng JSON có thể thành một đối tượng / mảng 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;
}

0

Đây là một hàm đơn giản và hiệu suất mà tôi đã tạo (sử dụng xác thực chuỗi cơ bản trước khi sử dụng json_decodecho các chuỗi lớn hơn):

function isJson($string) {
    $response = false;

    if (
        is_string($string) &&
        ($string = trim($string)) &&
        ($stringLength = strlen($string)) &&
        (
            (
                stripos($string, '{') === 0 &&
                (stripos($string, '}', -1) + 1) === $stringLength
            ) ||
            (
                stripos($string, '[{') === 0 &&
                (stripos($string, '}]', -1) + 2) === $stringLength
            )
        ) &&
        ($decodedString = json_decode($string, true)) &&
        is_array($decodedString)
    ) {
        $response = true;
    }

    return $response;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.