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_matchRFC4627의 정규식 에 또한 유효 기간을 확인 :

  // 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') == NULLnull유효한 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.