PHP json_decode ()는 유효한 JSON으로 NULL을 반환합니까?


104

이 JSON 개체는 일반 텍스트 파일에 저장되어 있습니다.

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

로 디코딩하려고하면 json_decode()NULL이 반환됩니다. 왜? 파일을 읽을 수 있습니다 (반향을 시도했지만 정상적으로 file_get_contents()작동했습니다).

http://jsonlint.com/ 에 대해 JSON을 테스트 했으며 완벽하게 유효합니다.

여기서 뭐가 잘못 됐나요?

해결책

Google에서 답변을 찾고 SO : json_decode returns NULL after webservice call . 내 JSON 파일에는 UTF BOM 시퀀스 (있을 수없는 일부 이진 문자)가 있으므로 JSON 구조가 손상되었습니다. 16 진수 편집기로 이동하여 바이트를 지 웠습니다. 모든 것이 정상으로 돌아 왔습니다. 왜 이런 일이 발생 했습니까? Microsoft Windows의 메모장을 사용하여 파일을 편집했기 때문입니다. 끔찍한 생각!


5
PHP 5.2.9로 작업하기; 따라서 사용할 수 없습니다 json_last_error().
Joel A. Villarreal Bertoldi

1
또한 파일 중간에 다른 잘못된 문자가있을 때 발생할 수 있습니다. 문자열에 MS Word에서 붙여 넣은 다음 잘못 인코딩 된 특수 en-dash 중 하나가 포함되어 있기 때문에 json_decode ()가 null을 반환했습니다. 잠재적 인 문제 문자를 식별하려면 JSON 파일 (Notepad ++에서 사용)을 열고 인코딩을 변경 (변환하지 않음) 한 다음 복사본으로 저장합니다. 그런 다음 두 파일을 비교합니다 (WinMerge 사용).
LinusR

(Windows 메모장 문제),이 문의하시기 바랍니다, 내가 너무 문제를 공유하고 그것을 고정 : stackoverflow.com/questions/10290849/...
펠릭스 Aballi


저에게는 특별한 것이 아니라 개체 요소 끝에 추가 쉼표가 추가되었습니다. Take away : JSON을 일관되지 않게 만드는 모든 것이 오류를 발생시킵니다. 보너스 팁 : jsonviewer.stack.hu를 믿지 마십시오. jsonlint
Aman Alam

답변:


68

특수 문자의 인코딩 일 수 있습니다. 명확한 정보를 얻기 위해 json_last_error () 를 요청할 수 있습니다.

업데이트 : 문제가 해결되었습니다. 질문의 "해결 방법"단락을보십시오.


응용 프로그램을 시작한 이후로 특수 문자를 사용해 왔으며 이전에는 문제가 없었습니다. 로컬에서 JSON 디코딩은 완벽하게 작동합니다. 내 서버에서는 그렇지 않습니다. 그리고 json_last_error()PHP 5.2.9이기 때문에 전화를 걸 수 없습니다 . 이 함수는 PHP 5.3.0에 나타납니다.
Joel A. Villarreal Bertoldi

1
아니, 작동합니다. 지금은 더 이상 테스트를 할 수 없습니다. 나중에 확인하면 여기에 게시하겠습니다. 또한 사용자가 제공 한 메모에는 몇 가지 힌트가 있습니다. de.php.net/json_decode가 도움이 될 수 있습니다.
Pekka

1
나를 위해 PHP 5.3에서 텍스트가 UTF-8로 인코딩되면 잘 작동합니다. 그러나 텍스트를 utf8_decode()먼저 전달하면 json_decode()조용히 실패합니다.
마태 복음

1
@Pekka Google에서 답변을 찾고 나는 다음으로 돌아 왔습니다. stackoverflow.com/questions/689185/json-decode-returns-null-php . 내 JSON 파일에는 UTF BOM 시퀀스 (있을 수없는 일부 이진 문자)가 있으므로 JSON 구조가 손상되었습니다. 16 진수 편집기로 이동하여 바이트를 지 웠습니다. 모든 것이 정상으로 돌아 왔습니다. 왜 이런 일이 발생 했습니까? Micro $ oft Windows의 메모장을 사용하여 파일을 편집했기 때문입니다. 끔찍한 생각!
Joel A. Villarreal Bertoldi

2
이것은 PHP 사람들에게 버그로보고되어야합니다. BOM이 유효한 UTF8이면 조용히 멈춰서는 안됩니다.
jmucchiello

86

이것은 나를 위해 일했습니다.

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );

2
나는 이것을 사용하고 배열을 얻었지만 내 언어 특정 문자 (ş, ç, ö, ..)도 삭제되었습니다.
zkanoca 2014

5
json 데이터가 UTF-8로 인코딩 된 경우 (또는 내가 추측하는 UTF 인코딩)은 올바르지 않습니다. 유효한 UTF-8 인코딩 데이터를 제거합니다. 파일에 영어 만 포함되어있는 한 작동하지만 항상 위험한 가정입니다. 나는 이것을 사용하지 않을 것입니다.
DaedalusAlpha 2015 년

이것으로 작동하지만 그것 없이는 두 문자열이 동일하지도 않습니다. 나는 뭔가를 놓치고 있습니까?
Rudie Visser 2016-08-25

작동합니다! 근데 왜? 디코딩을 시도 문자열 나는 그것에서 특별한 문자가 없었어요
토비아스 정보 Gassmann

대박. 나를 위해 일했습니다. :)
Sohil

31

시도해 볼 수 있습니다.

json_decode(stripslashes($_POST['data']))

실수로 stripslashes()두 번 호출하여 필수 슬래시를 제거하고 잘못된 JSON 문자열을 발생 시켰습니다. 이 답변은 오류를 발견하는 데 도움이되었습니다
Philipp

22

크롬에서 요청을 확인하면 JSON이 텍스트 인 것을 볼 수 있으므로 JSON에 빈 코드가 추가되었습니다.

다음을 사용하여 지울 수 있습니다.

$k=preg_replace('/\s+/', '',$k);

그런 다음 다음을 사용할 수 있습니다.

json_decode($k)

print_r 그러면 배열이 표시됩니다.


감사합니다. 누락 된 영어를 찾으시기 바랍니다.
Dean_Wilson

당신은 전설이고 하루 종일 이것으로 생각하고 있습니다.
Sboniso Marcus Nzimande

나를 위해 했어요 !! 내가 만든 간단한 조정은 교체에 공백을 추가하고 이것을 사용하고 있으며 내 공간도 교체하는 것 같습니다. 이제 잘 작동합니다. $k=preg_replace('/\s+/', ' ',$k);
Kash

문제는 이것은 모든 단일 공백을 제거하여 영어 텍스트를 모두 함께 붙입니다.
CodeGuru

14

나는 똑같은 문제가 있었고 디코딩하기 전에 따옴표 문자를 대체하여 간단히 해결했습니다.

$json = str_replace('"', '"', $json);
$object = json_decode($json);

내 JSON 값은 JSON.stringify 함수에 의해 생성되었습니다.


이 경우 htmlspecialchars 함수가 사용 중일 수 있으며 더 이상 JSON을 구문 분석 할 수 없습니다. 반대로 바꾸려면 & quot;를 수동으로 바꾸는 대신 "htmlspecialchars_decode"함수가 있습니다.
Davy

11

숨겨진 문자가 json을 엉망으로 만들 수 있습니다.

$json = utf8_encode($yourString);
$data = json_decode($json);

위의 모든 솔루션을 시도한 후 마침내 이것이 저에게 효과적이었습니다. 정말 감사합니다!!
Anis R.

7
$k=preg_replace('/\s+/', '',$k); 

나를 위해 해냈어. 예, Chrome에서 테스트합니다. 사용자에게 Thx


4

오늘이 문제를 만났을 때 이것을 추가 할 것이라고 생각했습니다. JSON 문자열을 둘러싼 문자열 패딩이있는 경우 json_decode는 NULL을 반환합니다.

PHP 변수가 아닌 소스에서 JSON을 가져 오는 경우 먼저 "트림"하는 것이 좋습니다.

$jsonData = trim($jsonData);

4

이것은 오류 유형을 이해하는 데 도움이됩니다.

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

2

한 번만 저장하십시오. 나는 그것이 단지 html 인코딩 문제라는 것을 알아 내기 위해 3 시간을 보냈다. 이 시도

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$json_errors = array(
JSON_ERROR_NONE => 'No error has occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
);
echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
print_r($param);

1

Jürgen Math가 user2254008에 의해 나열된 preg_replace 메서드를 사용하여 언급했듯이 저를 위해 수정했습니다.

이것은 Chrome에만 국한되지 않고 문자 집합 변환 문제인 것 같습니다 (적어도 제 경우에는 유니 코드-> UTF8). 이것은 내가 겪었던 모든 문제를 해결했습니다.

미래의 노드로서, 내가 디코딩하고 있던 JSON Object는 Python의 json.dumps 함수에서 나왔습니다. 이로 인해 다른 비위생적 인 데이터가 쉽게 처리되었지만 다른 데이터가 전송되었습니다.


1

데이터베이스에서 json을 얻는 경우

mysqli_set_charset($con, "utf8");

연결 링크 $ con 정의 후


감사합니다 TomoMiha. 이것은 특수 문자를 포함하는 MySQL의 모든 문제에 정확히 맞는 것이며 json_decode로 변환했을 때 해당 특정 필드가 산출되었습니다 = null ....
KLL


1

제 경우에는 JSON 문자열의 작은 따옴표 때문입니다.

JSON 형식은 키와 문자열 값에 큰 따옴표 만 허용합니다.

예:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

Javascript 구문 때문에 혼란스러워졌습니다. 물론 Javascript에서는 다음과 같이 할 수 있습니다.

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

하지만 나중에 해당 객체를 JSON 문자열로 변환 할 때 :

JSON.stringify(json); // "{"hello":"PHP"}"

0

JSON을 인쇄 한 다음 페이지 소스 (CTRL / CMD + U)를 확인하여이 문제를 해결했습니다.

print_r(file_get_contents($url));

<pre>꼬리표 가있는 것으로 밝혀졌습니다 .


0

당신은 이러한 점을 확인해야

1. 당신의 json 문자열에는 알 수없는 문자가 없습니다.

2. json 문자열은 온라인 json 뷰어에서 볼 수 있습니다. (Google에서 온라인 뷰어로 검색하거나 json 파서로 검색 할 수 있습니다.) 오류없이 볼 수 있습니다.

삼. 문자열에 html 엔티티가 없으므로 일반 텍스트 / 문자열이어야합니다.

포인트 3에 대한 설명

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

~ (htmlentities () 함수 제거)

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

0

나를 위해 json_decode ()가 올바르게 작동하도록 하려면 error_reporting 을 꺼야했습니다 . 이상하게 들리지만 제 경우에는 사실입니다. 디코딩하려는 JSON 문자열 사이에 일부 알림이 인쇄되어 있기 때문입니다.


0

기억해야 할 가장 중요한 것은 유효한 JSON 데이터에서 NULL 결과를 얻을 때 다음 명령을 사용하는 것입니다.

json_last_error_msg();

즉.

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

그런 다음 다음과 같이 수정합니다.

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

0

그래서 html_entity_decode ()가 저에게 효과적이었습니다. 이것을 시도하십시오.

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

-5
<?php 
$json_url = "http://api.testmagazine.com/test.php?type=menu";
$json = file_get_contents($json_url);
$json=str_replace('},

]',"}

]",$json);
$data = json_decode($json);

echo "<pre>";
print_r($data);
echo "</pre>";
?>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.