json_encodeはNULLを返しますか?


119

何らかの理由で、アイテム「description」が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、2009

これらのフィールドはすべて$r['description']、for()ステートメントの外側のエコーを実行するだけの場合、エコー出力されますか?
タルンフェルド2009

または、$ r ['description']のコンテンツの例が役立つかもしれません。それはどのデータ型ですか?
mopoke 2009

データベースシェマのスクリーンショットを作成していただけませんか?;-)
ストリートパレード2009

回答:


256

utf8以外のエンコーディングでデータを取得しているに違いありません。クエリのmysql_query('SET CHARACTER SET utf8')前に配置してくださいSELECT


5
こんにちは、この答えは私の命を救いました、ありがとう。私も同じ問題を抱えていました。「ValidaçãodeFormulários」のような非utf8文字の値がありました。私はこの質問が少し古いことを知っていますが、それがインターネットの素晴らしさです!!
fabio

7
PHP 5.2.3以降、セキュリティ上の理由からmysql_set_charsetの方が適しています。詳細については、php.net / manual / en / function.mysql-set-charset.phpを参照してください。
masakielastic 2013年

3
UTF8はWeb上の共通語だからです。追加のパラメーターとオーバーヘッドでAPIを乱雑にする代わりに、PHPは(厳密に)最も一般的なエンコーディングを使用します。一般的でない(または場合によってはほとんど使用されていない)エンコーディングを使用すると、変換の負担が残ります。
NTD 2013年

1
これを行う推奨方法が変更されました。この回答を編集してリンクを含めようとしましたが、拒否されました。正しい方法は、以下の私の答えです。
bejs

1
@VeeKフィールドをUTF-8で保存するだけでは不十分です。UTF-8でクライアントに応答するようにサーバーを構成する必要があります。私の知る限り、mysqlとmariadbはlatin1を使用しています。
ntd 2017

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 2013年

9

数日前、1つのテーブルで同じ問題が発生しました。

まず試してください:

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

最後の行が5を返す場合、問題はデータにあります。テーブルはUTF-8ですが、入力されたデータではありません。たとえば、入力はtxtファイルでしたが、愚かなエンコーディング(私の場合はWin-1250 = CP1250)でWinマシン上に作成され、このデータはDBに入力されています。

解決?新しいデータ(Excel、Webページ)を探し、PSPad(またはその他)を介してソースtxtファイル編集しエンコーディングをUTF-8に変更し、すべての行を削除して、元のデータを配置します。保存する。DBに入力します。

エンコーディングをutf-8に変更して、すべての行を手動で変更することもできます(colsに特殊文字-descなどを指定します)。奴隷に良い...


または、JSON_PARTIAL_OUTPUT_ON_ERRORオプションを使用して問題を確認します(UTF8のフィールドはnullになります)。
Peter Krauss

6

utf8エンコードされた文字列をjson_encodeで渡す必要があります。以下のように使用utf8_encodeしてarray_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_arrayby keyとbyの両方の値を返しますint。インデックスを使用しないので、emをフェッチしないでください。

これが本当にの問題である場合json_encode、ループの本体を次のようなものに置き換えることをお勧めします

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

パーパスには、物事をいじくっているいくつかの特別な文字があります...


[{"id": "4"、 "name": "ノート2"、 "説明":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、2009

@tarnfield:ええと、それはあなたが望むものかそうでないものですか?ああ..そこにいくつかの追加情報があります...ここに...それを修正しましょう。
mpen 2009

「description」が返されますnull
tarnfeld、2009

説明が戻ってきた場合は、nullおそらくそうです nullecho $row['description'].'<br/>';そのループで試して、それが何を言っているかを確認してください。
mpen 2009

1
こんにちは、この答えは私の命を救いました、ありがとう。私も同じ問題を抱えていました。「ValidaçãodeFormulários」のような非utf8文字の値がありました。私はこの質問が少し古いことを知っていますが、それがインターネットの素晴らしさです!!
ファビオ


3

PDOを使用するすべての人にとって、解決策はntdの回答に似ています

PHP PDO :: __構造のページ、ユーザーからのコメントとして生きドットコムでKiipa

UTF-8文字セットを取得するには、DSNでそれを指定できます。

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


0

私にとって、json_encodeがエンティティのnullエンコーディングを返す問題は、jsonSerialize実装が関連エンティティのオブジェクト全体をフェッチしたためでした。jsonでシリアル化するオブジェクトに関連付けられたエンティティが複数ある場合に、関連/関連付けられたエンティティのIDをフェッチして-> toArray()を呼び出すようにして、問題を解決しました。注:私はimplements JsonSerializableエンティティに関するケースについて話している。


-4

同じ問題があり、解決策は自分の関数を使用することでした json_encode()

echo '["' . implode('","', $row) . '"]';
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.