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

Любые идеи?

tarnfeld
источник
Прежде всего заключим ключи массива в кавычки.
Joost
Не могли бы вы предоставить информацию о схеме вашего "штатного" стола. Есть ли столбец под названием описание?
mopoke
все эти поля будут отображаться эхом, если я просто сделаю эхо за $r['description']пределами оператора for ()?
tarnfeld
Или, возможно, поможет какой-нибудь пример содержимого из $ r ['description']. Какой это тип данных?
mopoke
не могли бы вы сделать скриншот схемы базы данных? ;-)
streetparade

Ответы:

256

Бьюсь об заклад, вы получаете данные в кодировке, отличной от utf8: попробуйте поставить mysql_query('SET CHARACTER SET utf8')перед SELECTзапросом.

NTD
источник
5
привет, этот ответ спас мне жизнь, спасибо. У меня здесь была такая же проблема. У меня были значения с символами, отличными от utf8, например «Validação de Formulários». Я знаю, что этот вопрос немного устарел, но в этом вся прелесть Интернета !!
fabio
7
mysql_set_charset лучше по соображениям безопасности с PHP 5.2.3. См. Подробности на php.net/manual/en/function.mysql-set-charset.php .
masakielastic 03
3
Потому что UTF8 - это лингва-франка в сети. Вместо того, чтобы загромождать API дополнительными параметрами и накладными расходами, PHP (строго) использует наиболее распространенную кодировку, оставляя вам бремя преобразования, если вы используете необычную (или почти мертвую, как в вашем случае) кодировку.
ntd
1
Рекомендуемый способ сделать это теперь изменен. Я попытался отредактировать этот ответ, включив ссылку, но получил отказ. Правильный способ - в моем ответе ниже.
bejs
1
@VeeK недостаточно хранить ваши поля в UTF-8: вы должны настроить свой сервер для ответа клиентам в UTF-8. AFAIK, запасные mysql и mariadb используют latin1.
НТД
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

Anwser ntd не решил мою проблему. Для тех, кто находится в такой же ситуации, вот как я, наконец, справился с этой ошибкой: просто 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, но не введенные данные . Например, ввод был в текстовом файле, но создан на машине Win с глупой кодировкой (в моем случае Win-1250 = CP1250), и эти данные были введены в БД.

Решение? Найдите новые данные (Excel, веб-страницу), отредактируйте исходный текстовый файл через PSPad (или что-то еще), измените кодировку на UTF-8 , удалите все строки и теперь поместите данные из оригинала. Сохранить. Войдите в БД .

Вы также можете изменить кодировку только на utf-8, а затем вручную изменить все строки (укажите столбцы со специальными символами - desc, ...). Хорошо для рабов ...

Иво Урбанек
источник
или используйте JSON_PARTIAL_OUTPUT_ON_ERRORопцию, чтобы увидеть проблему (например, поле с UTF8 будет пустым).
Питер Краусс
6

Вы должны передать строку в кодировке utf8 в json_encode. Вы можете использовать utf8_encodeи array_map()работать, как показано ниже:

<?php
    $encoded_rows = array_map('utf8_encode', $rows);
    echo json_encode($encoded_rows);
?>
Koder
источник
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);
?>
  • При повторении mysql_num_rowsвы должны использовать <not <=. Вы также должны кэшировать это значение (сохранить его в переменной) вместо того, чтобы пересчитывать его каждый цикл. Кто знает, что он делает под капотом ... (может быть эффективным, я не совсем уверен)
  • Вам не нужно явно копировать каждое значение таким образом ... вы просто усложняете себе задачу. Если запрос возвращает больше значений, чем вы указали там, укажите только те, которые вы хотите в своем SQL.
  • mysql_fetch_arrayвозвращает значения как by, так keyи by int. Вы не используете индексы, поэтому не выбирайте их.

Если это действительно проблема json_encode, то могу ли я предложить заменить тело цикла чем-то вроде

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

Возможно, там есть некоторые особые символы, которые все портят ...

mpen
источник
[{"id": "4", "name": "Noter 2", "description": null, "icon": "http: \ / \ / images.apple.com \ / webapps \ / performance \ / 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 \ / performance \ / images \ /noter2_20091223182720-thumb.jpg "," date ":" 1262032317 "," company ":" dBelement, LLC "," companyurl ":" http: \ / \ /dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com»
Tarnfeld
@tarnfield: Ты этого хочешь или нет? О ... у вас есть дополнительная информация ... здесь ... позвольте мне исправить это для вас.
mpen
да, "описание" возвращаетсяnull
Тарнфельд
Если описание возвращается, nullто, вероятно, так и есть null . Попробуйте echo $row['description'].'<br/>';в этом цикле и посмотрите, что он говорит.
mpen
1
привет, этот ответ спас мне жизнь, спасибо. У меня здесь была такая же проблема. У меня были значения с символами, отличными от utf8, например «Validação de Formulários». Я знаю, что этот вопрос немного устарел, но в этом вся прелесть Интернета !!
fabio
3

Для всех, кто использует PDO, решение аналогично ответу ntd .

Со страницы конструкции PHP PDO :: __ в качестве комментария пользователя Kiipa в live dot com :

Чтобы получить кодировку UTF-8, вы можете указать это в DSN.

$ link = новый PDO ("mysql: host = localhost; dbname = DB; charset = UTF8 ");

Michaels
источник
0

Для меня проблема, при которой json_encode возвращала нулевую кодировку сущности, заключалась в том, что моя реализация jsonSerialize извлекала целые объекты для связанных сущностей; Я решил проблему, убедившись, что я получил идентификатор связанной / связанной сущности и вызвал -> toArray (), когда с объектом для сериализации json было связано несколько сущностей. Обратите внимание, я говорю о случаях, когда one implements JsonSerializableon entity.

Виктор С
источник
-4

У меня была такая же проблема, и я решил использовать мою собственную функцию вместо json_encode()

echo '["' . implode('","', $row) . '"]';
Лачи
источник