web-dev-qa-db-ja.com

PHP json_encodeエンコード番号を文字列として

PHP json_encode関数に1つの問題があります。数字を文字列としてエンコードします。

array('id' => 3)

になる

"{ ["id": "3", ...)

Jsはこれらの値を検出すると、それらを文字列として解釈し、数値演算はそれらで失敗します。 json_encodeが数字を文字列としてエンコードするのを防ぐ方法を知っている人はいますか?ありがとうございました!

131
Chris Barnhill

私は非常に簡単なテストを行いました:

$a = array(
    'id' => 152,
    'another' => 'test',
    'ananother' => 456,
);
$json = json_encode($a);
echo $json;

これは、私が間違えなければ、あなたが説明するもののように思えますか?

そして、私は出力として得ています:

{"id":152,"another":"test","ananother":456}

したがって、この場合、整数は文字列に変換されていません。


それでも、これは使用しているPHPのバージョンに依存する可能性があります。PHPのバージョンに応じて、json_encodeに関連するバグが修正されています。

このテストはPHP 5.2.6で行われました。 PHP 5.2.9および5.3.0でも同じことがわかります。テストする別の5.2.xバージョンはありませんが、:

どのバージョンのPHPを使用していますか?または、テストケースは投稿した例よりも複雑ですか?

---(http://bugs.php.net/ に関する1つのバグレポートが関連している可能性がありますか?たとえば、 バグ#40503:json_encode整数変換はPHPと一致しません


たぶん バグ#3868 興味があるかもしれませんが、

28
Pascal MARTIN

PHP 5.3.3以降、数値の自動変換では フラグがあります であることに注意してください(optionsパラメーターはPHP 5.3.0で追加されました)。

$arr = array( 'row_id' => '1', 'name' => 'George' );
echo json_encode( $arr, JSON_NUMERIC_CHECK ); // {"row_id":1,"name":"George"}
322
Rijk

私も、DB(PostgreSQL)から読み取りを行っていましたが、すべてが文字列でした。各行をループし、それを使用して最終結果配列を作成します。

$result_arr[] = array($db_row['name'], (int)$db_row['count']);

ループ内で強制的に整数値にする。 json_encode($result_arr)を実行すると、数値として正しくフォーマットされます。これにより、データベースから取得する数値とそうでない数値を制御できます。

編集:

json_encode()関数には、JSON_NUMERIC_CHECKフラグを2番目の引数として使用して、これをオンザフライで実行する機能もあります。ただし、ドキュメントのこのユーザーの例に示すように(以下にコピー)、慎重に使用する必要があります。 http://uk3.php.net/manual/en/function.json-encode.php#106641

<?php
// International phone number
json_encode(array('phone_number' => '+33123456789'), JSON_NUMERIC_CHECK);
?>

そして、このJSONを取得します。

{"phone_number":33123456789}
33
mouckatron

同じ問題が発生しています(PHP-5.2.11/Windows)。私はこの回避策を使用しています

$json = preg_replace( "/\"(\d+)\"/", '$1', $json );

これは、引用符で囲まれたすべての(負ではない整数)数値を数値自体に置き換えます(「 "42"」は「42」になります)。

PHPマニュアルのこのコメント も参照してください。

8
oli_arborum

$arr = array('var1' => 100, 'var2' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);
を試してください

ただし、PHP 5.3.3でのみ機能します。このPHP json_encode変更ログを見てください http://php.net/manual/en/function.json-encode.php#refsect1-function.json-encode-changelog

7
habibillah

次のテストでは、型を文字列に変更するとjson_encode()が数値をJSON文字列として返すことを確認します(つまり、二重引用符で囲みます)。 settype(arr ["var"]、 "integer")またはsettype($ arr ["var"]、 "float")を使用して修正してください。

<?php

class testclass {
    public $foo = 1;
    public $bar = 2;
    public $baz = "Hello, world";
}

$testarr = array( 'foo' => 1, 'bar' => 2, 'baz' => 'Hello, world');

$json_obj_txt = json_encode(new testclass());
$json_arr_txt = json_encode($testarr);

echo "<p>Object encoding:</p><pre>" . $json_obj_txt . "</pre>";
echo "<p>Array encoding:</p><pre>" . $json_arr_txt . "</pre>";

// Both above return ints as ints. Type the int to a string, though, and...
settype($testarr["foo"], "string");
$json_arr_cast_txt = json_encode($testarr);
echo "<p>Array encoding w/ cast:</p><pre>" . $json_arr_cast_txt . "</pre>";

?>
3

Pascal MARTIN は、ここで十分な信用を得ていません。 JSONが返されるたびに数値をチェックすることは、数百のサーバー側関数を備えた既存のプロジェクトでは実行できません。

Php-mysqlをphp-mysqlndに置き換えたところ、問題はなくなりました。数字は数字、文字列は文字列、ブール値はブール値です。

2
Rory Jarrard

完全を期すために(まだコメントを追加できないため)、この詳細を別の回答として追加します。

(編集:ソースデータ(つまり、OPの場合、データベース結果セット)が(数値列を文字列として返すことによって)問題になる可能性があり、実際にはjson_encode()が問題の原因ではないことを認識した後に読む

両方の「 mysql_fetch_array 」のマニュアルページ:

取得した行に対応する文字列の配列を返します。

...および " mysql_ fetch_ row ":

フェッチされた行に対応する文字列の数値配列を返します

明確に述べている;返される配列のエントリは文字列になります。

(私はphpBB2でDBクラスを使用していました(はい、それは時代遅れです!)、そのクラスの「sql_fetchrow()」メソッドは「mysql_fetch_array()」を使用します)

それに気づかずに、私もこの質問を見つけて問題を理解することになりました! :)

Pascal Martinがフォローアップコメントで上記に述べたように、ソースで「不正な型」の問題を処理するソリューションを信じています(つまり、「 mysql_field_type() "関数を使用して、一般的には、フェッチの直後にキャストする(または「オブジェクト」のような他のフェッチメソッド?)方が良いでしょう。

2
OzgurH

データベースからのデータの処理でも同じ問題がありました。基本的に問題は、jsonで変換する配列の型が、整数ではなく文字列としてPHPによって認識されることです。私の場合、行をカウントするDB列からデータを返すクエリを作成しました。 PDOドライバーは、列をintとしてではなく、文字列として認識します。影響を受ける列でintとしてキャストを実行することで解決しました。

0
balucio

問題が発生した場合は、(int)を使用できます!!それは正常に動作します。

0
Rahul Gupta
$rows = array();
while($r = mysql_fetch_assoc($result)) {
    $r["id"] = intval($r["id"]); 
    $rows[] = $r;
}
print json_encode($rows);  
0
Yar

それはPHPバージョンの問題であり、同じ問題が私のPHPバージョンを5.6にアップグレードして問題を解決しました

0
Peter Allen

値をintまたはfloatにキャストすると修正されるようです。例えば:

$coordinates => array( 
    (float) $ap->latitude,
    (float) $ap->longitude 
);
0
Derrick Miller