PHP json_decode () trả về NULL với JSON hợp lệ?


104

Tôi có đối tượng JSON này được lưu trữ trên một tệp văn bản thuần túy:

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

Khi tôi cố gắng giải mã nó bằng json_decode(), nó trả về NULL. Tại sao? Tệp có thể đọc được (tôi đã thử echo file_get_contents()và nó hoạt động tốt).

Tôi đã thử nghiệm JSON chống lại http://jsonlint.com/ và nó hoàn toàn hợp lệ.

Có gì sai ở đây?

Giải pháp

Đang tìm kiếm câu trả lời trên Google, tôi quay lại SO: json_decode trả về NULL sau cuộc gọi webservice . Tệp JSON của tôi có chuỗi UTF BOM (một số ký tự nhị phân không nên có), do đó, phá vỡ cấu trúc JSON. Đã đến Hex Editor, đã xóa các byte. Mọi thứ trở lại bình thường. Tại sao điều này đã xảy ra? Bởi vì tôi đã chỉnh sửa tệp bằng Microsoft Windows 'Notepad. Ý tưởng kinh khủng!


5
Làm việc với PHP 5.2.9; do đó, tôi không thể sử dụng json_last_error().
Joel A. Villarreal Bertoldi,

1
Cũng lưu ý rằng điều này có thể xảy ra với các ký tự không hợp lệ khác ở giữa tệp. Tôi vừa có json_decode () trả về null vì chuỗi chứa một trong những dấu gạch ngang đặc biệt đó, có thể được dán từ MS Word và sau đó có thể bị mã hóa sai. Để xác định các ký tự có thể có vấn đề, hãy mở tệp JSON (tôi đã sử dụng trong Notepad ++), thay đổi mã hóa (không chuyển đổi) và lưu dưới dạng bản sao. Sau đó khác biệt hai tệp (tôi đã sử dụng WinMerge).
LinusR

(Windows Notepad vấn đề) Xin vui lòng, tham khảo ý kiến này, tôi chia sẻ những vấn đề quá và nó cố định nó: stackoverflow.com/questions/10290849/...
Felix Aballi


Đối với tôi, nó không có gì đặc biệt, chỉ là một dấu phẩy thừa ở cuối phần tử của một đối tượng. Bỏ đi: Bất cứ điều gì làm cho JSON của bạn không nhất quán sẽ gây ra lỗi. Mẹo thêm: không tin tưởng jsonviewer.stack.hu Sử dụng một cái gì đó giống như jsonlint
Aman Alam

Câu trả lời:


68

Nó có thể là bảng mã của các ký tự đặc biệt. Bạn có thể hỏi json_last_error () để có được thông tin xác định.

Cập nhật: Vấn đề đã được giải quyết, hãy xem đoạn "Giải pháp" trong câu hỏi.


Tôi đã sử dụng các ký tự đặc biệt kể từ khi bắt đầu ứng dụng và không có vấn đề gì trước đây. Ở địa phương, giải mã JSON hoạt động hoàn hảo. Trên máy chủ của tôi, nó không. Và tôi không thể gọi json_last_error()vì nó là PHP 5.2.9. Hàm đó xuất hiện trên PHP 5.3.0.
Joel A. Villarreal Bertoldi,

1
Không, điều này sẽ hoạt động. Tôi không thể thực hiện thêm thử nghiệm ngay bây giờ, nếu có sau, tôi sẽ đăng ở đây. Cũng có một vài gợi ý trong ghi chú do người dùng đóng góp: de.php.net/json_decode có thể có gì đó hữu ích.
Pekka

1
Đối với tôi, trên PHP 5.3, nó hoạt động tốt khi văn bản được mã hóa bằng UTF-8. Nhưng nếu tôi chuyển văn bản qua utf8_decode()trước, sau đó json_decode()âm thầm thất bại.
Matthew

1
@Pekka Đang tìm kiếm câu trả lời trên Google, tôi quay lại SO: stackoverflow.com/questions/689185/json-decode-returns-null-php . Tệp JSON của tôi có chuỗi UTF BOM (một số ký tự nhị phân không nên có), do đó, phá vỡ cấu trúc JSON. Đã đến Hex Editor, đã xóa các byte. Mọi thứ trở lại bình thường. Tại sao điều này đã xảy ra? Vì tôi đã chỉnh sửa tệp bằng Micro $ oft Windows 'Notepad. Ý tưởng kinh khủng!
Joel A. Villarreal Bertoldi,

2
Điều này sẽ được báo cáo là một lỗi đối với người dùng PHP. Nếu BOM là UTF8 hợp lệ, nó sẽ không bị nghẹt thở.
jmucchiello

86

Điều này đã làm việc cho tôi

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

2
Tôi đã sử dụng cái này và nhận được mảng nhưng các ký tự dành riêng cho ngôn ngữ của tôi (ş, ç, ö, ..) cũng bị xóa.
zkanoca

5
Điều này không chính xác nếu dữ liệu json được mã hóa UTF-8 (hoặc bất kỳ mã hóa UTF nào mà tôi đoán). Nó sẽ xóa dữ liệu được mã hóa UTF-8 hợp lệ. Nó có thể sẽ hoạt động miễn là tệp chỉ chứa ngôn ngữ tiếng Anh, nhưng đó luôn là một giả định rủi ro. Tôi sẽ không sử dụng cái này.
DaedalusAlpha

Với điều này, nó hoạt động nhưng không có nó thì không, ngay cả khi hai chuỗi giống hệt nhau, tôi có thiếu cái gì đó không?
Rudie Visser

nó hoạt động! nhưng tại sao? chuỗi Tôi cố gắng để giải mã không có bất kỳ ký tự đặc biệt trong đó
Tobias Gassmann

Tuyệt vời. Đã làm cho tôi. :)
Sohil

31

Bạn có thể thử với nó.

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

Tôi đã vô tình gọi stripslashes()hai lần, điều này đã loại bỏ các dấu gạch chéo cần thiết và gây ra chuỗi JSON không hợp lệ. Câu trả lời này đã giúp tôi phát hiện ra lỗi
Philipp

22

Nếu bạn kiểm tra yêu cầu trong chrome, bạn sẽ thấy rằng JSON là văn bản, vì vậy đã có mã trống được thêm vào JSON.

Bạn có thể xóa nó bằng cách sử dụng

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

Sau đó, bạn có thể sử dụng:

json_decode($k)

print_r sau đó sẽ hiển thị mảng.


Cảm ơn vì điều này - hy vọng bạn tìm thấy tiếng Anh còn thiếu của mình.
Dean_Wilson

Con người bạn là huyền thoại, đã vật lộn với điều này cả ngày.
Sboniso Marcus Nzimande

Đã làm cho tôi !! Một tinh chỉnh đơn giản mà tôi đã thực hiện là thêm một khoảng trống trong phần thay thế, tôi đang sử dụng cái này và nó dường như cũng thay thế cho khoảng trống của tôi. hoạt động tốt bây giờ. $k=preg_replace('/\s+/', ' ',$k);
Kash

Vấn đề là, điều này loại bỏ mọi khoảng trắng, làm cho tất cả các văn bản tiếng Anh bị dính vào nhau phải không?
CodeGuru

14

Tôi đã gặp vấn đề tương tự và tôi đã giải quyết nó đơn giản bằng cách thay thế ký tự trích dẫn trước khi giải mã.

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

Giá trị JSON của tôi được tạo bởi hàm JSON.stringify.


Trong trường hợp này, hàm htmlspecialchars có thể đã được sử dụng và JSON không thể được phân tích cú pháp nữa. Để đảo ngược nó, có chức năng "htmlspecialchars_decode" thay vì thay thế thủ công & quot;
Davy

11

Có thể một số ký tự ẩn đang gây rối với json của bạn, hãy thử điều này:

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

Sau khi thử tất cả các giải pháp ở trên, giải pháp này cuối cùng đã làm việc cho tôi. Cảm ơn rất nhiều !!
Anis R.

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

đã làm điều đó cho tôi. Và có, đang thử nghiệm trên Chrome. Thx cho người dùng2254008


4

Tôi chỉ nghĩ rằng tôi sẽ thêm điều này, khi tôi gặp vấn đề này hôm nay. Nếu có bất kỳ phần đệm chuỗi nào xung quanh chuỗi JSON của bạn, json_decode sẽ trả về NULL.

Nếu bạn đang lấy JSON từ một nguồn không phải là một biến PHP, bạn nên "cắt" nó trước:

$jsonData = trim($jsonData);

4

điều này giúp bạn hiểu loại lỗi là gì

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

Chỉ cần tiết kiệm một thời gian. Tôi đã dành 3 giờ để tìm ra rằng đó chỉ là vấn đề mã hóa html. Thử cái này

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

Như đã nêu bởi Jürgen Math bằng cách sử dụng phương thức preg_replace được liệt kê bởi user2254008 đã sửa nó cho tôi.

Điều này không chỉ giới hạn ở Chrome, nó dường như là một vấn đề chuyển đổi bộ ký tự (ít nhất là trong trường hợp của tôi, Unicode -> UTF8) Điều này đã khắc phục tất cả các vấn đề tôi đang gặp phải.

Là một nút trong tương lai, Đối tượng JSON mà tôi đang giải mã đến từ hàm json.dumps của Python. Điều này lại khiến một số dữ liệu mất vệ sinh khác lọt qua mặc dù nó đã được xử lý dễ dàng.


1

Nếu bạn đang nhận json từ cơ sở dữ liệu, hãy đặt

mysqli_set_charset($con, "utf8");

sau khi xác định kết nối liên kết $ con


Cảm ơn TomoMiha. Đây chính xác là những gì phù hợp với tất cả các vấn đề của tôi với MySQL có chứa các ký tự đặc biệt và khi được chuyển đổi bởi json_decode, trường cụ thể đó đã được trả về = null ....
KLL


1

Đối với trường hợp của tôi, đó là do một dấu ngoặc kép trong chuỗi JSON.

Định dạng JSON chỉ chấp nhận dấu ngoặc kép cho các khóa và giá trị chuỗi.

Thí dụ:

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

Tôi đã nhầm lẫn điều này vì cú pháp Javascript. Trong Javascript, tất nhiên, chúng ta có thể làm như sau:

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

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

nhưng sau đó khi chuyển đổi các đối tượng đó thành chuỗi JSON:

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

0

Tôi đã giải quyết vấn đề này bằng cách in JSON, sau đó kiểm tra nguồn trang (CTRL / CMD + U):

print_r(file_get_contents($url));

Hóa ra có một <pre>thẻ theo sau .


0

bạn nên đảm bảo những điểm này

1. chuỗi json của bạn không có bất kỳ ký tự ẩn số nào

2. chuỗi json có thể xem từ trình xem json trực tuyến (bạn có thể tìm kiếm trên google dưới dạng trình xem trực tuyến hoặc trình phân tích cú pháp cho json) nó sẽ xem mà không có bất kỳ lỗi nào

3. chuỗi của bạn không có thực thể html, nó phải là văn bản / chuỗi thuần túy

để giải thích điểm 3

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

để (loại bỏ hàm htmlentities ())

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

0

Đối với tôi, tôi đã phải tắt error_reporting , để json_decode () hoạt động chính xác. Nghe có vẻ kỳ lạ, nhưng đúng trong trường hợp của tôi. Bởi vì có một số thông báo được in giữa chuỗi JSON mà tôi đang cố gắng giải mã.


0

Điều quan trọng nhất cần nhớ, khi bạn nhận được kết quả NULL từ dữ liệu JSON hợp lệ là sử dụng lệnh sau:

json_last_error_msg();

I E.

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

Sau đó, bạn khắc phục điều đó bằng:

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

0

Vì vậy, html_entity_decode () đã làm việc cho tôi. Hãy thử cái này.

$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>";
?>
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.