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

您能否提供有关“职员”表的架构的信息。是否有称为描述的列?
mopoke

如果我只是简单地$r['description']在for()语句之外进行回显,那么所有这些字段都会回显?
tarnfeld

也许$ r ['description']中的一些示例内容会有所帮助。它是什么数据类型?
mopoke

您可以制作数据库shema的屏幕截图吗?;-)
streetparade

Answers:


256

我敢打赌,您正在以非utf8编码检索数据:请尝试mysql_query('SET CHARACTER SET utf8')SELECT查询之前输入。


5
嗨,这个答案救了我一命,谢谢。我在这里遇到同样的问题。我对非utf8字符(例如“ValidaçãodeFormulários”)具有价值。我知道这个问题现在有点老了,但是那真是互联网的绝妙!!
fabio

7
从PHP 5.2.3开始,出于安全原因,mysql_set_charset更好。有关详细信息,请参见php.net/manual/en/function.mysql-set-charset.php
masakielastic

3
因为UTF8是网络上的通用语言。PHP(严格地)使用最常用的编码,而不是使API杂乱无章地增加额外的参数和开销,如果您使用的是不常见的编码(在您的情况下几乎是死的),则给您带来转换负担。
2013年

1
推荐的执行方法现已更改。我试图编辑此答案以包含链接,但被拒绝了。正确的方法是在下面的答案中。
bejs 2014年

1
@VeeK不足以将字段存储在UTF-8中:您必须配置服务器以对UTF-8中的客户端进行应答。AFAIK库存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的答案无法解决我的问题。对于处于相同情况的用户,这是我最终如何处理此错误的方法:只需对每个结果进行utf8_encode。

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

希望能帮助到你!


我也有编码问题。w /混合编码。我找到的解决方案:stackoverflow.com/a/3521396/776345
Paschalis,

9

几天前,我有1张桌子的相同问题。

首先尝试:

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

如果最后一行返回5,则问题出在您的data上。我知道,您的表格位于UTF-8中,但未输入data。例如,输入是在txt文件中,但是是在Win机器上以愚蠢的编码创建的(在我的情况下是Win-1250 = CP1250),并且此数据已输入到DB中。

解?查找新数据(excel,网页),通过PSPad 编辑源txt文件(或其他方法),将编码更改为UTF-8,删除所有行,然后从原始文件中放入数据。保存。输入DB

您也只能将编码更改为utf-8,然后手动更改所有行(为cols提供特殊字符-desc,...)。对奴隶有好处...


或使用JSON_PARTIAL_OUTPUT_ON_ERROR选项查看问题(例如,带有UTF8的字段为空)。
彼得·克劳斯

6

您应该在json_encode中传递utf8编码的字符串。您可以像下面这样使用utf8_encodearray_map()运行:

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

4

啊!这看起来很不对劲,伤了我的头。试试更多类似的东西...

<?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你应该使用<<=。您还应该缓存该值(将其保存到变量中),而不是让它重新计算每个循环。谁知道它在做什么呢...(可能有效率,我不确定)
  • 您不需要像这样显式地复制每个值……您只是在加倍努力。如果查询返回的值比您在此列出的值多,请仅在SQL中列出所需的值。
  • mysql_fetch_array返回by key和by 的值int。您没有使用索引,所以不要获取em。

如果这确实是一个问题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

是的“描述”返回null
塔恩费尔德

如果说明返回,null则可能 null。尝试echo $row['description'].'<br/>';在该循环中查看其内容。
mpen

1
嗨,这个答案救了我一命,谢谢。我在这里遇到同样的问题。我对非utf8字符(例如“ValidaçãodeFormulários”)具有价值。我知道这个问题现在有点老了,但这就是互联网的超赞!!
fabio


3

对于使用PDO的任何人,解决方案都类似于ntd的答案

PHP PDO :: __ construct页面,作为用户Kiipa在live dot com的评论

要获取UTF-8字符集,可以在DSN中指定它。

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


0

对我来说,json_encode将返回实体的空编码的问题是因为我的jsonSerialize实现获取了相关实体的整个对象。我通过确保获取与相关/关联实体的ID并在与要进行json序列化的对象关联的实体有多个时调用-> toArray()来解决了该问题。注意,我说的是implements JsonSerializable关于实体的情况。


-4

我遇到了同样的问题,解决方案是使用自己的函数而不是 json_encode()

echo '["' . implode('","', $row) . '"]';
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.