json_encode đang trả về NULL?


119

Vì một số lý do, mục "mô tả" trả về NULLvới mã sau:

<?php
include('db.php');

$result = mysql_query('SELECT * FROM `staff` ORDER BY `id` DESC LIMIT 2') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>

Đây là lược đồ cho cơ sở dữ liệu của tôi:

CREATE TABLE `staff` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` longtext COLLATE utf8_unicode_ci,
  `description` longtext COLLATE utf8_unicode_ci,
  `icon` longtext COLLATE utf8_unicode_ci,
  `date` longtext COLLATE utf8_unicode_ci,
  `company` longtext COLLATE utf8_unicode_ci,
  `companyurl` longtext COLLATE utf8_unicode_ci,
  `appurl` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Đây là những gì được lặp lại trên trang:

[{"id":"4","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"},{"id":"3","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"}]

Có ý kiến ​​gì không?


Trước hết, hãy đặt các khóa mảng trong dấu ngoặc kép.
Joost

Bạn có thể cung cấp thông tin về lược đồ của bảng "nhân viên" của bạn. Có một cột được gọi là mô tả?
mopoke

tất cả các trường này sẽ vang lên nếu tôi chỉ đơn giản thực hiện một tiếng vang $r['description']bên ngoài câu lệnh for ()?
tarnfeld

Hoặc có lẽ một số nội dung mẫu từ $ r ['description'] sẽ hữu ích. Nó là loại dữ liệu gì?
mopoke

bạn có thể tạo một ảnh chụp màn hình của shema cơ sở dữ liệu? ;-)
streetparade

Câu trả lời:


256

Tôi cá là bạn đang truy xuất dữ liệu ở dạng mã hóa non-utf8: hãy thử đặt mysql_query('SET CHARACTER SET utf8')trước SELECTtruy vấn của bạn .


5
chào, câu trả lời này đã cứu mạng tôi, cảm ơn bạn. Tôi đã gặp vấn đề tương tự ở đây. Tôi có các giá trị với các ký tự không phải utf8 như "Validação de Formulários". Tôi biết câu hỏi này bây giờ hơi cũ, nhưng đó là sự tuyệt vời của Internet !!
fabio

7
mysql_set_charset tốt hơn vì lý do bảo mật kể từ PHP 5.2.3. Xem php.net/manual/en/ Chức năng.mysql-set-charset.php để biết chi tiết.
masakielastic

3
Bởi vì UTF8 là ngôn ngữ phổ biến trên web. Thay vì làm lộn xộn API với các tham số bổ sung và chi phí, PHP (nghiêm túc) sử dụng kiểu mã hóa phổ biến nhất, để lại cho bạn gánh nặng chuyển đổi nếu bạn sử dụng kiểu mã hóa không phổ biến (hoặc gần như đã chết, như trong trường hợp của bạn).
ntd

1
Cách đề xuất để làm điều này hiện đã thay đổi. Tôi đã cố gắng chỉnh sửa câu trả lời này để bao gồm một liên kết nhưng đã bị từ chối. Cách chính xác là trong câu trả lời của tôi dưới đây.
bejs

1
@VeeK không đủ để lưu trữ các trường của bạn trong UTF-8: bạn phải định cấu hình máy chủ của mình để trả lời các ứng dụng khách trong UTF-8. Cổ phiếu AFAIK mysql và mariadb sử dụng latin1.
ntd,

118

Nếu bạn có ít nhất PHP 5.5, bạn có thể sử dụng json_last_error_msg () , nó sẽ trả về một chuỗi mô tả sự cố.

Nếu bạn không có 5.5, nhưng đang bật / trên 5.3, bạn có thể sử dụng json_last_error () để xem vấn đề là gì.

Nó sẽ trả về một số nguyên mà bạn có thể sử dụng để xác định vấn đề trong tài liệu của hàm . Hiện tại (2012.01.19), các số nhận dạng là:

0 = JSON_ERROR_NONE
1 = JSON_ERROR_DEPTH
2 = JSON_ERROR_STATE_MISMATCH
3 = JSON_ERROR_CTRL_CHAR
4 = JSON_ERROR_SYNTAX
5 = JSON_ERROR_UTF8

Những điều này có thể thay đổi trong các phiên bản tương lai, vì vậy tốt hơn hết bạn nên tham khảo sách hướng dẫn.

Nếu bạn dưới 5.3 là bạn đã hết may, không có cách nào để hỏi lỗi là gì.


18

ntd's anwser đã không giải quyết được vấn đề của tôi. Đối với những người trong cùng tình huống, đây là cách cuối cùng tôi đã xử lý lỗi này: Chỉ cần utf8_encode từng kết quả của bạn.

while($row = mysql_fetch_assoc($result)){
    $rows[] = array_map('utf8_encode', $row);
}

Hy vọng nó giúp!


Tôi cũng gặp sự cố mã hóa. w / mã hóa hỗn hợp. giải pháp tôi tìm thấy: stackoverflow.com/a/3521396/776345
Paschalis

9

cách đây vài ngày, tôi gặp sự cố CÙNG với 1 bảng.

Trước hết hãy thử:

echo json_encode($rows);
echo json_last_error();  // returns 5 ?

Nếu dòng cuối cùng trả về 5, thì dữ liệu của bạn có vấn đề . Tôi biết, các bảng của bạn ở UTF-8, nhưng chưa nhập dữ liệu . Ví dụ: đầu vào là tệp txt, nhưng được tạo trên máy Win với mã hóa ngu ngốc (trong trường hợp của tôi là Win-1250 = CP1250) và dữ liệu này đã được nhập vào DB.

Giải pháp? Tìm kiếm dữ liệu mới (excel, trang web), chỉnh sửa tệp txt nguồn qua PSPad (hoặc bất kỳ thứ gì khác), thay đổi mã hóa thành UTF-8 , xóa tất cả các hàng và bây giờ đặt dữ liệu từ bản gốc. Tiết kiệm. Nhập vào DB .

Bạn cũng chỉ có thể thay đổi mã hóa thành utf-8 và sau đó thay đổi tất cả các hàng theo cách thủ công (cung cấp cols bằng các ký tự đặc biệt - desc, ...). Tốt cho nô lệ ...


hoặc sử dụng JSON_PARTIAL_OUTPUT_ON_ERRORtùy chọn để xem vấn đề (ví dụ: trường có UTF8 sẽ là trống).
Peter Krauss

6

Bạn nên chuyển chuỗi mã hóa utf8 bằng json_encode. Bạn có thể sử dụng utf8_encodearray_map()hoạt động như bên dưới:

<?php
    $encoded_rows = array_map('utf8_encode', $rows);
    echo json_encode($encoded_rows);
?>

4

AHHH !!! Điều này trông rất sai lầm, nó làm tôi đau đầu. Hãy thử một cái gì đó giống như thế này ...

<?php
include('db.php');

$result = mysql_query('SELECT `id`, `name`, `description`, `icon` FROM `staff` ORDER BY `id` DESC LIMIT 20') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>
  • Khi iterating trên mysql_num_rowsbạn nên sử dụng <không <=. Bạn cũng nên lưu giá trị này vào bộ nhớ cache (lưu nó vào một biến) thay vì để nó đếm lại mỗi vòng lặp. Ai biết nó đang làm gì ... (có thể hiệu quả, tôi không thực sự chắc chắn)
  • Bạn không cần phải sao chép từng giá trị một cách rõ ràng như vậy ... bạn chỉ đang tự làm điều này trở nên khó khăn hơn. Nếu truy vấn trả về nhiều giá trị hơn bạn đã liệt kê ở đó, hãy chỉ liệt kê những giá trị bạn muốn trong SQL của mình.
  • mysql_fetch_arraytrả về các giá trị bằng keyvà bằng int. Bạn không sử dụng các chỉ số, vì vậy đừng tìm nạp chúng.

Nếu điều này thực sự là một vấn đề với json_encode, thì tôi có thể đề xuất thay thế phần thân của vòng lặp bằng một cái gì đó như

$rows[] = array_map('htmlentities',$row);

Perhpas có một số ký tự đặc biệt trong đó có thể làm hỏng mọi thứ ...


[{"id": "4", "name": "Noter 2", "description": null, "icon": "http: \ / \ / images.apple.com \ / webapps \ / energy \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ / dbelement.com \ / "," appurl ":" http: \ / \ / noter2.dbelement.com "}, {" id ":" 3 "," name ":" Noter 2 "," description ": null," icon ":" http: \ / \ / images .apple.com \ / webapps \ / energy \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ /dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com "
tarnfeld

@tarnfield: Chà, đó có phải là điều bạn muốn hay không? Ồ..bạn có một số thông tin bổ sung trong đó ... đây ... để tôi sửa giúp bạn.
mpen

vâng "mô tả" trả vềnull
tarnfeld

Nếu mô tả quay trở lại nullthì có thể là như vậy null . Hãy thử echo $row['description'].'<br/>';trong vòng lặp đó và xem nó nói gì.
mpen

1
xin chào, câu trả lời này đã cứu mạng tôi, cảm ơn bạn. Tôi đã gặp vấn đề tương tự ở đây. Tôi có các giá trị với các ký tự không phải utf8 như "Validação de Formulários". Tôi biết câu hỏi này bây giờ hơi cũ, nhưng đó là sự tuyệt vời của Internet !!
fabio


3

Đối với bất kỳ ai sử dụng PDO, giải pháp tương tự như câu trả lời của ntd .

Từ trang cấu trúc PHP PDO :: __ , dưới dạng nhận xét từ người dùng Kiipa tại live dot com :

Để có được bộ ký tự UTF-8, bạn có thể chỉ định mã đó trong DSN.

$ link = new PDO ("mysql: host = localhost; dbname = DB; charset = UTF8 ");


0

Đối với tôi, một vấn đề mà json_encode sẽ trả về mã hóa null của một thực thể là do việc triển khai jsonSerialize của tôi đã tìm nạp toàn bộ đối tượng cho các thực thể có liên quan; Tôi đã giải quyết vấn đề bằng cách đảm bảo rằng tôi đã tìm nạp ID của thực thể có liên quan / được liên kết và gọi -> toArray () khi có nhiều hơn một thực thể được liên kết với đối tượng được tuần tự hóa json. Lưu ý, tôi đang nói về các trường hợp một implements JsonSerializabletrên các thực thể.


-4

Tôi đã gặp vấn đề tương tự và giải pháp là sử dụng chức năng của riêng tôi thay vì json_encode()

echo '["' . implode('","', $row) . '"]';
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.