json_encode가 NULL을 반환합니까?


119

어떤 이유로 항목 "설명" NULL이 다음 코드와 함께 반환 됩니다.

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

내 데이터베이스의 스키마는 다음과 같습니다.

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

페이지에 표시되는 내용은 다음과 같습니다.

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

어떤 아이디어?


먼저 배열 키를 따옴표로 묶어 보겠습니다.
Joost

"staff"테이블의 스키마에 대한 정보를 제공 할 수 있습니까? 설명이라는 열이 있습니까?
mopoke

$r['description']for () 문 외부에서 단순히 에코를 수행하면 이러한 모든 필드가 에코됩니다 .
tarnfeld 2009

또는 $ r [ 'description']의 일부 예제 콘텐츠가 도움이 될 것입니다. 어떤 데이터 유형입니까?
포크 2009-12-28

데이터베이스 shema의 스크린 샷을 만들 수 있습니까? ;-)
streetparade

답변:


256

UTF8이 아닌 인코딩으로 데이터를 검색하고 있다고 확신합니다 . 쿼리 mysql_query('SET CHARACTER SET utf8')앞에 넣으 십시오 SELECT.


5
안녕하세요,이 답변이 제 생명을 구했습니다. 감사합니다. 나는 여기서 같은 문제를 겪고 있었다. "Validação de Formulários"와 같이 UTF8이 아닌 문자로 값을 가졌습니다. 나는이 질문이 조금 오래되었다는 것을 알고 있지만 그것은 인터넷의 굉장함입니다!
fabio

7
mysql_set_charset은 PHP 5.2.3부터 보안상의 이유로 더 좋습니다. 자세한 내용은 php.net/manual/en/function.mysql-set-charset.php 를 참조 하십시오.
masakielastic 2013-06-03

3
UTF8은 웹상의 링구아 프랑카이기 때문입니다. 추가 매개 변수와 오버 헤드로 API를 복잡하게 만드는 대신 PHP (엄격하게)는 가장 일반적인 인코딩을 사용하므로 일반적이지 않은 (또는 거의 죽은 경우) 인코딩을 사용하는 경우 변환 부담이 발생합니다.
ntd

1
이를 수행하는 권장 방법이 이제 변경되었습니다. 링크를 포함하도록이 답변을 편집하려고했지만 거부되었습니다. 올바른 방법은 아래 내 대답에 있습니다.
bejs

1
@VeeK 필드를 UTF-8로 저장하는 것만으로는 충분하지 않습니다 . UTF-8로 클라이언트에 응답 하도록 서버를 구성 해야합니다 . AFAIK stock mysql 및 mariadb는 latin1을 사용합니다.
ntd

118

PHP 5.5 이상이 있는 경우 문제를 설명하는 문자열을 반환하는 json_last_error_msg ()를 사용할 수 있습니다 .

5.5가 없지만 5.3 이상이면 json_last_error () 를 사용 하여 문제가 무엇인지 확인할 수 있습니다 .

함수 문서 에서 문제를 식별하는 데 사용할 수있는 정수를 반환합니다 . 현재 (2012.01.19) 식별자는 다음과 같습니다.

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

이는 향후 버전에서 변경 될 수 있으므로 설명서를 참조하는 것이 좋습니다.

5.3 미만이면 운이 좋지 않은 것입니다. 오류가 무엇인지 물어볼 방법이 없습니다.


18

ntd의 anwser가 내 문제를 해결하지 못했습니다. 같은 상황에있는 사람들을 위해 마지막으로이 오류를 처리 한 방법은 다음과 같습니다. 각각의 결과를 utf8_encode하십시오.

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

도움이 되었기를 바랍니다.


인코딩 문제도있었습니다. 혼합 인코딩 포함. 내가 찾은 솔루션 : stackoverflow.com/a/3521396/776345
Paschalis

9

며칠 전에 1 테이블에 동일한 문제가 있습니다.

먼저 시도해보십시오.

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

마지막 줄이 5를 반환하면 데이터에 문제가있는 것 입니다. 귀하의 테이블은 UTF-8이지만 입력 된 데이터는 아닙니다 . 예를 들어 입력은 txt 파일에 있었지만 어리석은 인코딩 (내 경우에는 Win-1250 = CP1250)으로 Win 시스템에서 생성되었으며이 데이터는 DB에 입력되었습니다.

해결책? 새 데이터 (엑셀, 웹 페이지) 를 찾고, PSPad (또는 기타)를 통해 소스 txt 파일편집하고 , 인코딩을 UTF-8로 변경 하고, 모든 행을 삭제 한 다음 원본에서 데이터를 넣습니다. 저장. DB에 들어가십시오 .

인코딩을 utf-8로만 변경 한 다음 모든 행을 수동으로 변경할 수도 있습니다 (특수 문자가있는 cols-desc, ...). 노예에게 좋다 ...


또는 JSON_PARTIAL_OUTPUT_ON_ERROR옵션 을 사용 하여 문제를 확인하십시오 (예 : UTF8이있는 필드는 null이 됨).
Peter Krauss

6

json_encode에 utf8 인코딩 된 문자열을 전달해야합니다. 아래와 같이 사용 utf8_encode하고 array_map()작동 할 수 있습니다 .

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

4

AHHH !!! 너무 잘못되어 머리가 아파요. 이런 식으로 더 시도하십시오 ...

<?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);
?>
  • 반복 할 때 not mysql_num_rows을 사용해야합니다 . 또한 모든 루프를 다시 계산하는 대신이 값을 캐시 (변수에 저장)해야합니다. 후드 아래에서 무엇을하는지 누가 알겠습니까? (효율적일 수 있습니다. 잘 모르겠습니다)<<=
  • 그렇게 명시 적으로 각 값을 복사 할 필요는 없습니다. 당신은 단지 이것을 더 어렵게 만드는 것입니다. 쿼리가 여기에 나열한 것보다 더 많은 값을 반환하는 경우 SQL에 원하는 값만 나열합니다.
  • mysql_fetch_arrayby key및 by 모두 값을 반환합니다 int. 인덱스를 사용하지 않으므로 가져 오지 마십시오.

이것이 정말로 문제라면 json_encode루프의 본문을 다음과 같이 바꾸는 것이 좋습니다.

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

Perhpas 거기에 뭔가를 비난하는 특별한 문자가 있습니다 ...


[{ "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 "
tarnfeld

@tarnfield : 글쎄, 당신이 원하는 건가요? 오 .. 거기에 몇 가지 추가 정보가 있습니다. 여기 ... 제가 고쳐 드릴게요.
mpen 2009

그래 "설명"반환null
tarnfeld

설명이 반환되면 null그것은 아마 이다 null . echo $row['description'].'<br/>';그 루프에서 시도 하고 그것이 말하는 것을 보십시오 .
mpen 2009

1
안녕하세요,이 답변이 제 생명을 구했습니다. 감사합니다. 나는 여기서 같은 문제를 겪고 있었다. "Validação de Formulários"와 같이 UTF8이 아닌 문자로 값을 가졌습니다. 나는이 질문이 조금 오래되었다는 것을 알고 있지만 그것은 인터넷의 굉장함입니다!
fabio


3

PDO를 사용하는 모든 사람에게 솔루션은 ntd의 답변 과 유사합니다 .

로부터 PHP PDO :: __ 구조 페이지 , 사용자의 주석으로 라이브 닷컴에서 Kiipa :

UTF-8 문자 집합을 얻으려면 DSN에서 지정할 수 있습니다.

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


0

나에게 json_encode가 엔티티의 null 인코딩을 반환하는 문제는 내 jsonSerialize 구현이 관련 엔티티에 대한 전체 객체를 가져 왔기 때문입니다. 관련 / 연관 엔터티의 ID를 가져 와서 json 직렬화 할 개체와 연결된 엔터티가 둘 이상있을 때-> toArray ()를 호출하여 문제를 해결했습니다. 참고로, implements JsonSerializable엔티티에 대한 사례에 대해 이야기하고 있습니다 .


-4

나는 같은 문제가 있었고 해결책은 대신 내 자신의 기능을 사용하는 것이 었습니다. json_encode()

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