質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

1733閲覧

PHPでデータベースから取得するデータを、JSONで得ているが 数値項目の値までも ダブルクォートでくくられている状況を回避したい(数値項目はダブルクォートはいらない)

saya24

総合スコア225

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/06/01 08:28

編集2020/06/01 09:44

下記で示しているコードは 掲載用に 簡易にしたヴァージョンですが、表題のとおり JSONで取得しているデータが
数値項目の値までも、ダブルクォートでくくられてしまっています。(下記はJSONデータの例:標準作業時間・更新カウンタは数値項目)

尚、これらデータを取得するためのSQL文は POSTでサーバに入ってくる作りになっています。

JSON

1[ 2 { 3 "品目コード": "123456", 4 "品名": "へのへのもへじ", 5 "標準作業時間": "0", 6 "標準収率": null, 7 "更新カウンタ": "9", 8 "更新日時": "19-04-01", 9 "更新担当者コード": "XXXXXXXXXX" 10 }, 11 { 12 "品目コード": "223456", 13 "品名": "こんやがやまだ", 14 "標準作業時間": "0", 15 "標準収率": null, 16 "更新カウンタ": "9", 17 "更新日時": "19-05-01", 18 "更新担当者コード": "XXXXXXXXXX" 19 }, 20 { 21 "品目コード": "323456", 22 "品名": "おしりふくかいちょう", 23 "標準作業時間": "0", 24 "標準収率": null, 25 "更新カウンタ": "9", 26 "更新日時": "19-06-01", 27 "更新担当者コード": "XXXXXXXXXX" 28 }, 29 { 30 "品目コード": "423456", 31 "品名": "ありませんもんがっこう", 32 "標準作業時間": "0", 33 "標準収率": null, 34 "更新カウンタ": "9", 35 "更新日時": "19-07-01", 36 "更新担当者コード": "XXXXXXXXXX" 37 } 38]

数値項目の値については JSON上 ダブルクォートでくくらない形式には できないでしょうか?

この例に示しているように、SQL文が 可変してしまう=数値項目が どの列にいるか分からない、という状況です。

PHP

1<?php include "php_classes/classes.php"; #SQL Server接続のためのクラス ms0connect について記載されてる 2 3## パラメータの取得 4if (!isset($_POST["DBID"]) || !isset($_POST["SQL"])) { 5 http_response_code(500); //HTTPレスポンスコード(500サーバーエラー) 6 echo "no parameter"; 7 exit(); 8} 9 10 11# SQL文 12$sql = $_POST["SQL"]; 13 14 15try { 16 //DBへの接続 【php_classes/classes.phpに接続先は書いてあります】 17 $db = new ms0connect(); 18 $conn = $db->dbconnect(); 19 $stmt = $conn->query($sql); 20 $results = $stmt->fetchAll(PDO::FETCH_ASSOC); 21 $conn = null; 22} catch (Exception $e) { 23 error_log("### SQL Serverデータ取得失敗 ⇒".$sql."###".$e->getMessage(),0); 24 http_response_code(569); //HTTPレスポンスコード(500サーバーエラー) 25 die("Error:" . $e->getMessage()); 26} 27 28$json = $results; //JSONに登録 29 30http_response_code(200); //HTTPレスポンスコード(200正常終了) 31header('Content-Type: application/json; charset=UTF-8'); 32header("X-Content-Type-Options: nosniff"); 33 34echo json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); //エンコードして送信 35exit(); 36 37 38 39function e(string $str, string $charset = 'UTF-8'): string { 40 return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, $charset); 41} 42?>

よろしくお願いします! 無理か否かさえ分からないので、ご見解を頂けたら幸いです。

2020/06/01 18:42追記

data

1array ( 20 => array ( '品目コード' => '123456', '品名' => 'へのへのもへじ', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), 31 => array ( '品目コード' => '223456', '品名' => 'こんやがやまだ', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '4', '更新日時' => '09-04-01', '更新担当者コード' => 'XXXXXXXXXX', ), 42 => array ( '品目コード' => '323456', '品名' => 'おしりふくかいちょう', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), 53 => array ( '品目コード' => '423456', '品名' => 'ありませんもんがっこう', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), ) 6[ { "品目コード": "123456", "品名": "へのへのもへじ", "標準作業時間": "0", "標準収率": null, "更新カウンタ": "7", "更新日時": "18-04-02", "更新担当者コード": "XXXXXXXXXX" }, 7{ "品目コード": "223456", "品名": "こんやがやまだ", "標準作業時間": "0", "標準収率": null, "更新カウンタ": "4", "更新日時": "09-04-01", "更新担当者コード": "XXXXXXXXXX" }, 8{ "品目コード": "323456", "品名": "おしりふくかいちょう", "標準作業時間": "0", "標準収率": null, "更新カウンタ": "7", "更新日時": "18-04-02", "更新担当者コード": "XXXXXXXXXX" }, 9{ "品目コード": "423456", "品名": "ありませんもんがっこう", "標準作業時間": "0", "標準収率": null, "更新カウンタ": "7", "更新日時": "18-04-02", "更新担当者コード": "XXXXXXXXXX" } ]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/06/01 08:33

何が問題でしょうか。
m.ts10806

2020/06/01 08:34

というか何か不都合起きてますでしょうか
saya24

2020/06/01 08:44 編集

自分が示したJSONデータ内の、標準作業時間、更新カウンタは データベース上数値項目なので、値がダブルクォートでくくられて欲しくないのです。 "標準作業時間": "0",    じゃなくて    "標準作業時間": 0,  が希望です。 今しがた json_encodeに 「 JSON_NUMERIC_CHECK」のオプションの追加を試しましたが、状況変わらず...やはりだめかなぁ
tanat

2020/06/01 08:54

echo json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); の一行前に var_export($json); を追記した結果を質問に追記お願いします。
saya24

2020/06/01 09:45

tanatさん、var_exportした結果を本文に追記しました
guest

回答3

0

実行しているPHPのバージョンが5.3.3より古いんじゃないでしょうか。
m.ts10806さんの回答にもある通り、JSON_NUMERIC_CHECKは5.3.3以降で使用可能です。

手元のPHP7.4環境だと以下の通りのエンコード結果になります。

PHP

1<?php 2 3// Your code here! 4 5$arr = array ( 60 => array ( '品目コード' => '123456', '品名' => 'へのへのもへじ', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), 71 => array ( '品目コード' => '223456', '品名' => 'こんやがやまだ', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '4', '更新日時' => '09-04-01', '更新担当者コード' => 'XXXXXXXXXX', ), 82 => array ( '品目コード' => '323456', '品名' => 'おしりふくかいちょう', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), 93 => array ( '品目コード' => '423456', '品名' => 'ありませんもんがっこう', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), ); 10var_dump(json_encode($arr,JSON_NUMERIC_CHECK|JSON_UNESCAPED_UNICODE ));

PHP7.2

1string(790) "[{"品目コード":123456,"品名":"へのへのもへじ","標準作業時間":0,"標準収率":null,"更新カウンタ":7,"更新日時":"18-04-02","更新担当者コード":"XXXXXXXXXX"},{"品目コード":223456,"品名":"こんやがやまだ","標準作業時間":0,"標準収率":null,"更新カウンタ":4,"更新日時":"09-04-01","更新担当者コード":"XXXXXXXXXX"},{"品目コード":323456,"品名":"おしりふくかいちょう","標準作業時間":0,"標準収率":null,"更新カウンタ":7,"更新日時":"18-04-02","更新担当者コード":"XXXXXXXXXX"},{"品目コード":423456,"品名":"ありませんもんがっこう","標準作業時間":0,"標準収率":null,"更新カウンタ":7,"更新日時":"18-04-02","更新担当者コード":"XXXXXXXXXX"}]"

手元に5.3.2以下のバージョンは無いので試していませんが、こんな感じにすればいけそうな気がします。(標準作業時間は常に整数である前提。実行はPHP7.4.1環境)

PHP

1$arr = array ( 20 => array ( '品目コード' => '123456', '品名' => 'へのへのもへじ', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), 31 => array ( '品目コード' => '223456', '品名' => 'こんやがやまだ', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '4', '更新日時' => '09-04-01', '更新担当者コード' => 'XXXXXXXXXX', ), 42 => array ( '品目コード' => '323456', '品名' => 'おしりふくかいちょう', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), 53 => array ( '品目コード' => '423456', '品名' => 'ありませんもんがっこう', '標準作業時間' => '0', '標準収率' => NULL, '更新カウンタ' => '7', '更新日時' => '18-04-02', '更新担当者コード' => 'XXXXXXXXXX', ), ); 6 7 8foreach($arr as $key => $val){ 9 $arr[$key]["標準作業時間"] = (int)$val["標準作業時間"]; 10} 11 12var_dump(json_encode($arr,JSON_UNESCAPED_UNICODE )); 13
string(806) "[{"品目コード":"123456","品名":"へのへのもへじ","標準作業時間":0,"標準収率":null,"更新カウンタ":"7","更新日時":"18-04-02","更新担当者コード":"XXXXXXXXXX"},{"品目コード":"223456","品名":"こんやがやまだ","標準作業時間":0,"標準収率":null,"更新カウンタ":"4","更新日時":"09-04-01","更新担当者コード":"XXXXXXXXXX"},{"品目コード":"323456","品名":"おしりふくかいちょう","標準作業時間":0,"標準収率":null,"更新カウンタ":"7","更新日時":"18-04-02","更新担当者コード":"XXXXXXXXXX"},{"品目コード":"423456","品名":"ありませんもんがっこう","標準作業時間":0,"標準収率":null,"更新カウンタ":"7","更新日時":"18-04-02","更新担当者コード":"XXXXXXXXXX"}]"

投稿2020/06/01 12:14

編集2020/06/01 12:25
tanat

総合スコア18713

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/06/01 12:27

わざわざ試していただけたのですね、それでデータのご提示を求められたのですね?? 自分の環境も7.4です。今、手元に環境がなく確認できないのですが、json_encodeに他2つのオプションを与えていることが気になり出しています。 シンプルにまず今回の目的のオプションだけにして試すべきですよねー、確認手順を失敗しました。 すみません、明日返事を改めます!
tanat

2020/06/01 12:38

> わざわざ試していただけたのですね、それでデータのご提示を求められたのですね?? そうですね。 最小限のコードで再現できる様に情報を整理すると適切な回答が得られやすくなりますね。(誰でも再現できるコードを作っているうちに自己解決することも多いです) 状況が再現できる最小限のコード(誰でも再現できるように、データを回答のような形でハードコーディングするとベスト)を作成してみて質問に追記されると、より解決に近づくと思います。
saya24

2020/06/02 03:54

申し訳ありません、昨日行ったjson_encodeの第二引数の指定方法に誤りがあったのか、本日JSON_NUMERIC_CHECKの指定を行ったところ 期待の結果を得ることができました。 皆様の貴重なお時間を頂いてしまい お詫びいたします
guest

0

ベストアンサー

目的が分からないですが、既に利用されているように、オプションを駆使してください。
JSON:定義済み定数

次の定数は、 json_encode() のオプションとして組み合わせて使用します。

JSON_NUMERIC_CHECK (integer)
数値形式の文字列を数値としてエンコードします。 PHP 5.3.3 以降で使用可能です。

例:

PHP

1<?php 2$ar = ["data"=>"123"]; 3echo json_encode($ar,JSON_NUMERIC_CHECK );

投稿2020/06/01 08:42

m.ts10806

総合スコア80854

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/06/01 08:49 編集

ご見解ありがとうございます、こちらのサイト<https://www.codelab.jp/blog/?p=1178>を参考に先ほど同じことを試したのですが、そちらで言及されているように、確実に作用してくれません....適用も状況は変わりありませんでした。
m.ts10806

2020/06/01 08:50

このオプションは型が文字列でも値が数字文字列ならちゃんと解釈してくれるので、なんとも言えません。 何か数字以外が混ざってるのでは。
saya24

2020/06/01 12:15

m.ts10806さん、ご提示いただきました簡易のコードを自分の環境で試してみるべきですよね?? この結果は、数字文字列であるため、JSONには値部分はダブルクォートは付かない、と予想されるわけですね?! 今、環境がないので明日試します。 ひょっとして、他のオプションが作用してが故のことがおきているのかな〜 端末持ち帰らず帰宅して失敗。
m.ts10806

2020/06/01 20:30

単体確認ならpaiza.ioでできます。 私もこの回答に提示するレベルならpaiza.io使ってます。 つまり、動作確認済みです。
saya24

2020/06/02 03:43

paiza.io、とても便利で今回の問合せで思いがけない収穫を得ることができました。ありがとうございます。サイト上の入力枠にご提示のコードを打ち込み実行したところ、もちろん数字左右にダブルクォートが現れることはありませんでした。 自分の環境で、試してどうなのか??と当初気になったのですが....別の検証を先に行ってしまい、新たな発見がありまして.... json_encodeの第二引数を、JSON_NUMERIC_CHECK単独で指定してみたのです。すると期待どおり、数字のみの文字列が ダブルクォートなしになっておりました。 (昨日は第二引数の指定を「 | 」でくくり、最後にJSON_NUMERIC_CHECKを追加した指定。期待した結果を得られなかったと記憶しています) JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINTの指定を既に行っていたので、この最後に付け足した、ということです。 ひょっとして 指定の順番では??と思い、先ほど最初にJSON_NUMERIC_CHECKを付け加えて実行を試したところ....無事目的が達成されました!! 「単なる指定の順番の問題であった」と認識して締めくくる思い出、最終確認で、最後の部分にJSON_NUMERIC_CHECKを再度指定して実行(期待結果を得ない想定で)したところ なんと無事 期待の結果を得てしまいました。となると.... 昨日単に、JSON_NUMERIC_CHECKの指定方法に 何か誤りがあった...ということぐらいしか思い当たりません。大変お騒がせで申し訳ないのですが 今日当該開発環境のApatchを再起動したといえばしたけれど
m.ts10806

2020/06/02 03:46

優先度の問題でしょうね。 指定の中には影響範囲が重複するものもあるでしょうから、 そういうときに内部的な優先度が働いていたという形かと思います。 いずれにしても「ミニマムな構成で試す」ことは徹底された方が良いかと思います。 問題切り分けのためには1つ1つ実証とって、問題個所を特定していく必要がありますから、時には一気に削ったり、組み合わせを変えてみたり、大胆な作業も必要になることでしょう。
saya24

2020/06/02 03:56

仰られる通りで、ぐ~のねも出ません。いい教訓になりました。 多くの方の時間を奪ってしまったことが悔やまれます、皆様ご親切にありがとうございました。
guest

0

テーブル上、標準作業時間・更新カウンタがint型になっていないのでは?
数値型の値はjson_encodeするときにダブルクォートはつきません

投稿2020/06/01 08:48

yambejp

総合スコア114968

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/06/01 10:01

ご見解ありがとうございます。今回の掲載はコードを抜粋しておりますが、MSのSQLServer以外 OracleDatabaseからデータを取得するSQL文にも対応した作りにしてまいます。 ご見解についてですが、SQLServer上でNUMERIC型、OracleでNUMBER型の項目が、JSON上で値の部分を””でくくられてしまっていることを 今しがた再確認しました。 ....PHP.iniにこの面の設定ってありましたかねぇ??? 何か自分の環境だけ 皆さまと違うような気が
tacsheaven

2020/06/01 23:43

NUMBER 型や NUMERIC 型の場合、数値型の変数(整数型・実数型)に入りきらない可能性があるので、ドライバ側で文字列として認識させている可能性があるかと思います。
saya24

2020/06/02 02:59

ご見解をありがとうございます。私も それを疑いだしていますが、m.ts10806さんの検証で、まずDBからのデータ取得部分か、自分が作成したデータでも事象が現れるか 確認したいと思います。 DBからのデータ取得部分だけ現れたら、プロバイダが怪しい....
tacsheaven

2020/06/02 03:49

PHP PDO の SQL Server ドライバは、ODBC を経由してたかと思います。なのでネイティブとはちょっと違った挙動をする可能性が……(プレースホルダーではまったことがあります)
saya24

2020/06/02 03:58

ありがとうございます、今回はプロバイダの起因ではなさそう、という判断をくだしました。ご親切に見解を頂けたこと 感謝を申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問