PHP에서 문자열이 JSON인지 확인하는 가장 빠른 방법은 무엇입니까?


385

문자열이 JSON인지 여부를 확인하는 정말 빠르고 빠른 방법이 필요합니다. 나는 이것이 최선의 방법이 아니라고 생각합니다.

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

성능 애호가라면이 방법을 개선하고 싶습니까?


3
json_decode한 번만 사용하십시오 ... 또한 입력 및 반환 값을 확인하십시오 json_decode.

5
그렇다면 어느 것이 답입니까?
— Farid Rn

8
여기서 삼항 스위치는 중복됩니다. 귀하의 진술은 이미 부울로 평가됩니다.
— 나는 곰 한 번 씨름했다.


Lewis Donovan의 대답을 받아들이십시오 ... 잘 작동합니다
— Poonam Bhatt

답변:


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

19
모두가이 답변을 좋아하는 것 같습니다. 왜 설명이 있습니까?
— Kirk Ouimet

8
나는 PHP 5.3>은 json_last_error 기능을 사용하는 데 필요한 것으로 판단
— 크리스 해리슨

97
대한 문자열의 첫 번째 문자 확인 {, [또는 다른 문자의 첫 번째 심볼 잠재적으로 크게 들어오는 문자열의 대부분이 비 JSON 것으로 예상 될 때까지이 일을 속도를 높일 수 있습니다.
— Oleg V. Volkov

20
$ phone = '021234567'; var_dump (isJson ($ phone)); 참을 돌려줘! false를 반환해야합니다.
— vee

23
이 함수는 문자열 또는 실제 숫자로 지정하더라도 모든 숫자에 대해 true를 리턴합니다. 6.5 = true, '300' = true, 9 = trueetc. 따라서 유효한 JSON 값일 수 있지만 {}또는 [];로 유효한 JSON 문자열 만 확인하려는 경우 함수가 예상대로 작동하지 않을 수 있습니다 .
— BadHorsie

156

질문에 대한 답변

이 함수 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)에 대한 추가 참고 사항

json_last_errorPHP 5.2에서는 지원되지 않기 때문에 인코딩 또는 디코딩이 boolean을 반환하는지 확인할 수 있습니다 FALSE. 여기에 예가 있습니다

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

이것이 도움이 되길 바랍니다. 행복한 코딩!


리틀 정밀이 JSON이 유효하지만 이전의 디코딩 하나 때문에 코드가 제대로 작동하려면 것입니다, 무효 인 경우 : " 반환 마지막 오류 (있는 경우) 중에 발생한 마지막 . 디코딩 / JSON 인코딩 "
— 브루노

감사합니다 @Madan, "json_decode"검증은 PHP 7.0을 실행하고 있다는 사실을 해결했습니다.
— Francis Rodrigues

분명히 json_decode는 리터럴 false에 대해 false를 반환 할 수 있으므로 ((strlen($json) === 5) && ($json !== 'false'))해당 에지를 피하기 위해 검사 를 수행해야합니까?
— MrMesees

@Bruno 마지막 디코딩이 오류없이 작동하면를 json_last_error반환합니다 JSON_ERROR_NONE.
— Andrea

81

당신이 정말로해야 할 일은 이것입니다 ...

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

이 요청에는 별도의 기능도 필요하지 않습니다. json_decode 주위에 is_object를 감싸고 계속 진행하십시오. 이 솔루션으로 사람들이 너무 많은 생각을하고있는 것 같습니다.


@ RomanM.Kos 배열이 간단한 배열 인 경우 명확하게하기 위해을 is_array추가로 사용해야 합니다 is_object. 그렇지 않으면 is_objectJSON으로 인코딩 된 간단한 배열에 대해 false를 반환합니다. 따라서이 경우 @ggutenberg가 맞습니다. true 인수를 전달하면 json_decode객체가 배열로 반환됩니다. 이론적으로 항상 디코드를 배열로 강제하고 검사 만하면 is_array됩니다.
— userabuser

@userabuser json_encode($array)간단한 PHP 배열의 경우 json_decode($str)객체를 수신하지만 배열은 수신하지 않습니다. json_decode($str, true)배열로 강제 변환합니다. 왜 코드에서 복잡한 문자열을 사용합니까? 확인 is_array(json_decode($str, true))하고 나중에 읽은 후에는 디코딩 된 배열이어야한다는 것을 이해할 것입니다. 추측하기가 훨씬 어렵습니다. is_object(json_decode($MyJSONArray))"아, 여기서는 디코딩 여부가 배열인지 아닌지"
— Roman M. Koss

올바른 아니에요 @ RomanM.Kos 아니, codepad.viper-7.com/OFrtsq - 내가 말했듯이, 당신은 항상 강제 할 수 json_decode는 객체와 배열을 검사 저장하는 배열을 반환하는 것이 아니라 당신이 아닌 경우 그리고 json_decode무엇 간단한 배열이었습니다. 객체가 아닌 디코딩시 배열을받습니다. JSON_FORCE_OBJECT간단한 배열을 전달하는 경우 항상 객체를 인 코드 할 때 강제로 사용하려면 사용해야 합니다.
— userabuser

11
말하는 공감대 : This request does not require a separate function even. 엄밀히 말하면 솔루션에는 별도의 기능이 필요하지 않습니다. 함수의 요점은 여러 줄의 코드를 한 줄의 코드처럼 보이게하는 것이 아닙니다 . 함수의 요점은 애플리케이션의 모든 곳에서 JSON 검사 프로세스를 표준으로 만들어 다른 프로그래머 (또는 시간이 지남에 따라 동일한 프로그래머)가 프로그램 흐름의 다른 단계에서 다른 검사 절차를 사용하지 않도록하는 것입니다.
— cartbeforehorse

71

사용 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));

그러나 벤치마킹에 신경 쓸만한 성능 애호가는 충분하지 않습니다.


11
: 전체 재귀 정규식 여기에 JSON을 확인합니다 stackoverflow.com/questions/2583472/regex-to-validate-json/...을 - 그러나 PHPs을 밝혀 json_decode빠른 PCRE 정규식보다 항상. (매우 최적화되지 않았지만 합성 테스트가 없으며 Perl.에서 다르게 동작 할 수 있습니다.)
— mario

3
@vee 네, 감사합니다. 그러나 여기에 [올바르게] 보관하지 마십시오. 실제로 프로덕션에서는 아무도 사용하지 않습니다.
— 마리오

1
@cartbeforehorse 좋아요, 감사합니다. PHP에서 큰 따옴표로 묶인 문자열 컨텍스트에서 이스케이프 건강을 수정했습니다.
— mario

1
@cartbeforehorse 그렇지 않습니다. 주로 장식. 실제로 이중 이스케이프가 필요한 리터럴 백 슬래시입니다. 들어 \r \n \tPHP 그들을 보간하지만, PCRE는 그 해석하지 않도록에만 의미가 있습니다 (만 필요했습니다 /x모드). 다른 일들은 꼭 필요하지는 않습니다. 그러나 여전히 모든 문자열 PHP 컨텍스트에서 "백 슬래시 자체가 이스케이프됩니다". 그래서 더 정확하게 생각할 수 있습니다.
— mario

4
@mario 알았어. 따라서 기본적으로 PHP는 정규 표현식 엔진이 그것을보기 전에 백 슬래시를 이스케이프 처리합니다. reg-exp 엔진에 관한 한, 우리가 보는 것처럼 문자열에 백 슬래시 수의 절반이 있습니다. "reg-exp처럼 복잡하지 않았다"
— cartbeforehorse

39

문자열이 json 배열 또는 객체를 나타내는 경우 true 를 반환 합니다 .

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

기술적으로 유효한 json이지만 숫자, 문자열 또는 부울 만 포함하는 json 문자열을 거부합니다.

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)

내가 생각해 낼 수있는 가장 짧은 방법입니다.


var_dump 대신 PHPUnit 테스트 케이스에 넣을 수 있습니다. 그렇지 않으면 나는 그것이 사실이라는 것을 알고 놀랐고 기쁘다.
— MrMesees

3
이것이 잘 작동 할 때 왜 다른 사람들이 그렇게 긴 대답을합니까? 감사.
— toddmo

1
간단히, 사랑스러운! "가장 빠른 방법"이나 성능을 현명하게 확인하지는 않았지만이 방법은 내가 확인한 모든 사례를 포함합니다. 이것은 악명 높은 속담 "너트를 깨기 위해 망치를 사용하지 마십시오"에 대한 전형적인 예입니다 . 프로그래머의 관점에서 볼 때 항상 코드를 단순하고 짧고 이해하기 쉽게 유지하는 것이 좋습니다. 성능 대 단순성은이 스레드의 범위를 벗어난 또 다른 논쟁입니다.
— Fr0zenFyr

이것은 깔끔한 논리이지만 빈 배열에 대해서는 false를 반환합니다. 예를 들면 다음과 같습니다 var_dump(isJson('[]')); // bool(false).. 부울에 대한 문서에 따르면, 이는 PHP에서 요소가 0 인 배열을 false로 평가하기 때문입니다. 다음은 반품 명세서를 조정하기위한 사소한 수정 사항입니다. 이 경우를 처리하는 디코딩 된 출력에 대해 동일한 비교를 수행합니다.return $json !== false && $str != $json;
— j13k

@ j13k 동일한 비교 isJson('hello')가 true로 평가 되는데 이는 유효한 json이 아닙니다. 느슨한 비교는 여기서 의도적으로 선택됩니다. 추악한 것을 제외하고는 빈 배열 / 객체 상황에 대한 빠른 해결책이 없습니다return $json == '[]' || ...
— Cyril

21

내가 사용하는 가장 간단하고 빠른 방법은 다음과 같습니다.

$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 인 경우 대가로 반환됩니다.


3
json_decode('null') == NULL및 null유효한 JSON 값이다.
— zzzzBov 1

json.parser.online 에서 'null'이 유효한 json인지 테스트 했지만 유효한 json이 아닌 것 같습니다. 그리고 json_decode () 는 json의 유효성을 검사하는 PHP 핵심 함수이므로 출력에 잘못된 결과를 얻지 못할 것입니다.
— Mohammad Mursaleen

확인되지 않은 일부 웹 사이트를 신뢰하기보다는 사양에 대한 문의를 고려하십시오 (2 페이지) . 또는 JSON.parse('null')개발자 콘솔에서 시도 하십시오.
— zzzzBov

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

잘못된 인코딩이 감지되면 http://tr.php.net/manual/en/function.json-decode.php 반환 값이 null입니다.


4
또한 "null"에 대해 null을 잘못 반환합니다 (유효한 JSON은 아니지만 그렇지 않으면 json_decode에 대해 "유효"할 수 있음). 그림을 이동.

나는 이것이 영혼이라고 생각합니다. json_decode($str)!=null;그렇지 않으면 함수가 호출되어야합니다 is_not_json.
— Yoshi

이 기능의 이름이 "JSON이 아닌 것"으로 바뀌 었습니다.
— lonesomeday

2
@ user166390 json_decode('null')은 spec에 따라 유효한 JSON 이며의 값을 반환해야합니다 null.
— zzzzBov

이 방법 is_json('false')을 사용 is_json('[]')하면 false유형을 선택하지 않은 상태로 반환 됩니다. 나는이 방법이 오히려 반환되어야한다고 생각한다 $str === null || json_decode($str) !== null.
— 앙투안 핀 사드

11

전달한 문자열이 비어 있지 않고 실제로 문자열인지 확인하려면 입력의 유효성을 검사해야합니다. 빈 문자열은 유효한 JSON이 아닙니다.

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

PHP에서는 JSON 객체 에 데이터 가 있는지 확인하는 것이 더 중요하다고 생각 합니다. 데이터를 사용하려면 json_encode()또는 을 사용해야하기 때문 json_decode()입니다. 빈 JSON 객체를 거부하여 빈 데이터에서 불필요하게 인코딩 및 디코딩을 실행하지 않는 것이 좋습니다.

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입니다.
— cartbeforehorse

그러나 '0'유효한 JSON이 아닙니다 ... 왜 조심해야합니까? @Kzqai
— Upful

11

이것은 그것을 할 것입니다 :

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합니다.

이를 실제로 보려면 다음 두 가지 예를 확인하십시오.


"hello"유효한 JSON이며, 그 대상도 배열이 아니라, json_last_error()충분
— JoniJnm

1
json_last_error()문자열 일 4때 오류 코드를 반환 json_decode()합니다 "hello". 여기 예 : 3v4l.org/lSsEo
— 루이스 도노반

귀하의 코드가 잘못 hello유효한 JSON 아니라 "hello"입니다 3v4l.org/OEJrQ
— JoniJnm

9

쉬운 방법은 JSON 결과를 확인하는 것입니다.

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

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

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

좋은 해결책. 타이핑 문제를 잘 처리합니다!
— 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

또 다른 간단한 방법

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

1
이것은 정확하지 않습니다. 모든 PHP 유형은 객체, 문자열 등과 같은 JSON으로 인코딩 될 수 있으며 json_decode 함수는이를 반환합니다. 이는 항상 배열을 디코딩하고 다른 변수 유형이없는 경우에만 해당됩니다.
— Chaoix

@Chaoix using json_decode($str,true)은 객체를 배열로 변환하여 is_array 검사를 통과시킵니다. 그래도 문자열, 정수 등을 수정합니다.
— Paul Phillips

json_encode의 두 번째 매개 변수에 대한 의미를 알 수 있습니다. 나는 여전히 @Ahad Ali의 솔루션이 입력과 알고리즘에서 json_decode를 한 번만 수행하는 측면에서 훨씬 더 나은 솔루션이라고 생각합니다.
— Chaoix

4

전달 된 문자열이 숫자가 아닌지 확인해야합니다.이 경우 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;
}

3

나는 그 해결책 중 일부를 시도했지만 아무것도 나를 위해 일하지 않았다. 나는이 간단한 것을 시도한다 :

$isJson = json_decode($myJSON);

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

두 번째 매개 변수가없는 JSON 디코딩이 객체를 제공하기 때문에 훌륭한 해결책이라고 생각합니다.

편집 : 입력 내용을 알고 있으면이 코드를 필요에 맞게 조정할 수 있습니다. 제 경우에는 "{"로 시작하는 Json이 있다는 것을 알고 있으므로 배열인지 확인할 필요가 없습니다.


JSON은 잠재적으로 배열 일 수 있으며,이 경우 stdClass 대신에 배열이됩니다. $ foo = "[1, 1, 2, 3]"; var_dump (json_decode ($ foo)); => array (4) {[0] => int (1) [1] => int (1) [2] => int (2) [3] => int (3)}
— Misha Nasledov

3

다음 클래스에서 PHPBench를 사용하면 다음과 같은 결과를 얻을 수 있습니다.

<?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 |
+---------------+-----------------------+-----+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+

결론 : json이 유효한지 확인하는 가장 빠른 방법은 return json_decode($json, true) !== null)입니다.


아주 좋은 :) 당신을 존경합니다
— Mahdi

3

어제 직장에서 비슷한 것을 발견 한 후에이 질문을 발견했습니다. 결국 내 솔루션은 위의 방법 중 일부의 하이브리드였습니다.

function is_JSON($string) {

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

  return $String_Is_JSON;
}

2

솔루션의 성능이나 우아함에 대해서는 잘 모르지만 사용하고 있습니다.

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

모든 JSON 인코딩 문자열은 { "로 시작하므로 RegEx를 사용하여이를 테스트하기에 충분합니다. RegEx에 능숙하지 않으므로 더 나은 방법이있을 수 있습니다. 또한 strpos () 가 더 빠를 수 있습니다.

내 tuppence 가치를 제공하려고합니다.

추신 /^[\[\{]\"/JSON 배열 문자열을 찾기 위해 RegEx 문자열을 업데이트했습니다 . 이제 문자열의 시작 부분에서 [ "또는 {"를 찾습니다.


2

다음과 같아야합니다.

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

문자열인지 확인하고 싶습니다. ErrorException문자열이 배열 또는 객체인지 피하기 위해 첫 번째 솔루션과 함께 잘 어울 립니다.
— sykez

1

이 답변 확장 다음은 어떻습니까?

<?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
해당 검사에서 오류가 발견되면 시간을 절약하기 위해 디코드를 실행하기 전에 하위 문자열 검사를 수행해서는 안됩니까? 4 개의 하위 문자열 검사가 json_decode보다 빠를 것이라고 생각할 것입니다. 그러나 누군가이 가정으로 나를 백업 할 수 있다면 이것에 대한 의견을 보내 주셔서 감사합니다.
— Mark

그것은 운임 논쟁이다. 처리 시간을 알지 못하지만 더 빠르면 예입니다.
— Sevenearths

1

안녕하세요 여기 내 라이브러리의 작은 조각이 있습니다.이 첫 번째 조건에서는 데이터가 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
    }
}

이 질문에 34 개의 답변이 게시되어 있으며, 그중 많은 것들은 JSON이 배열이나 객체를 나타내야한다고 (잘못) 믿고 있습니다. 이 답변이 다른 30 개의 답변과 다른 것을하고 있습니까?
— miken32

1

나에게서 또 다른 제안 :)

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

0

맞춤 기능

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

사례

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

}

자원

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


0

성공시 디코딩 된 데이터가 필요한 경우 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)

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
@ 디버깅 (오류를 숨기고)에 대한 사용하지만 절대적으로 권장하지 않습니다
— aswzen

0

가장 필요한 가능성을 다루기위한 헨릭의 답변에 대한 간단한 수정.

( "{} 및 []"포함)

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

가장 빠른 방법은하기 어쩌면 PHP는 객체 / 배열에 가능한 JSON 오브젝트를 디코딩 :

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

다음은 내가 만든 성능 있고 간단한 함수입니다 ( json_decode더 큰 문자열에 사용하기 전에 기본 문자열 유효성 검사를 사용함 ).

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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.