🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JSON

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

PHP

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

Q&A

解決済

2回答

2229閲覧

JSONで配列が作れない - PHP

kuma903

総合スコア9

JSON

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

PHP

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

0グッド

0クリップ

投稿2019/11/28 08:29

編集2019/11/28 14:13

JSONで配列を作りたい - PHP

いつもお世話になっております。
PHPでJSONを取得し配列を作りたいのですが、 syntax errorが起きてしまいます。
他のJSONファイルを利用するとエラーは起きませんが、ソースに記載のURLを参照するとエラーが起きます。

発生している問題・エラーメッセージ

print_rで syntax errorが起きています ※記載漏れのため追記 print_rでは表示されず、var_dumpで表示を行ったときにNULLが表示されます。 syntax errorとわかったのはjson_last_error()を使用して$json_arrを検査したためです。

該当のソースコード

PHP

1$url = "https://books.rakuten.co.jp/event/book/pocket-book/calendar/2019/11/js/booklist.json"; //新刊検索 2 3$json = file_get_contents($url); 4//$json = mb_convert_encoding($json, 'UTF-8', 'ASCII'); //元ファイルがUTF-8のため不要 5$json_arr = json_decode($json,true); 6 7print_r ($json_arr); 8

試したこと

変数一つ一つに文字コードを確認しましたが、$jsonまではUTF8、$json_arrはASCIIになっていました。
JSONファイルをダウンロードしてみたところ、UTF8で記載がありました。
また、GoogleChromeのJSONViewにて参照先のファイルを確認したところ、きちんと見ることができました。

バージョン

XAMPP :5.6.12
PHP :5.6.12
Apache:2.4.16

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

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

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

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

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

thyda.eiqau

2019/11/28 08:39

> print_rで syntax errorが起きています エラーメッセージは省略せず、表示された内容をコピペしてご提示ください。 print_rはechoと違い、式ではなく関数なので、print_r($json_arr)とする必要があります。
kuma903

2019/11/28 09:10

ご指摘ありがとうございます。 print_rの部分を訂正させて頂きました。
m.ts10806

2019/11/28 13:12

PHPのバージョンは幾つでしょうか。 質問本文に追記してください
kuma903

2019/11/28 14:14

コメントありがとうございます。 PHPのバージョンを追記しましたのでご覧ください。 不慣れなため、なにか不足している情報がありましたらコメントをお願い致します。
guest

回答2

0

ベストアンサー

PHP: print_r - Manual

print_r($json_arr);

老婆心ながら、
楽天ブックスの新刊カレンダーのjsonは非公式APIのようなので、
雑に扱うと良くない気がします。


php

1<html> 2<head> 3 <title>226112.php</title> 4</head> 5<body> 6<?php 7 8//$url = "https://books.rakuten.co.jp/event/book/pocket-book/calendar/2019/11/js/booklist.json"; //新刊検索 9//$json = file_get_contents($url); 10//file_put_contents('226112_data.json', $json); 11//exit; 12$json = file_get_contents('226112_data.json'); 13$json_arr = json_decode(preg_replace('/^\xEF\xBB\xBF/', '', $json), true); 14if (is_null($json_arr)) { 15 echo json_last_error() . PHP_EOL; 16 echo json_last_error_msg() . PHP_EOL; 17 exit; 18} 19$list = $json_arr['list']; 20echo "<p>" . PHP_EOL; 21foreach ($list as list($id,$url,$img,$eisbn,$date,$ttl,$ttl_kana,$athr,$dprc,$bprc,$ahid_id,$jun_id,$cpn_id,$ser_id,$lbl_id,$s_rec,$s_new,$s_res,$s_frc,$f_adlt,$fc1_id,$fc2_id,$fc3_id,$viewer_id,$viewer_url)) { 22 echo $ttl . "<br />" . PHP_EOL; 23} 24echo "</p>" . PHP_EOL; 25?> 26</body> 27</html> 28

こんな感じに雑サンプルコード。
直接取得したjsonファイルを処理するとSyntax errorになりますが、
UTF-8のBOM付きであるためなので、
preg_replaceを組み合わせれば回避できます。

投稿2019/11/28 08:37

編集2019/11/28 14:01
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kuma903

2019/11/28 09:14

回答ありがとうございます。 訂正させて頂きました。 エラーメッセージですが、print_rでは表示されず、var_dumpで表示を行ったときにNULLが表示されます。(この点も記載漏れで申し訳ございません。) syntax errorとわかったのはjson_last_error()を使用して$json_arrを検査したためです。
退会済みユーザー

退会済みユーザー

2019/11/28 09:30

そういう質問の本質的なところに関わる情報は、質問内容を編集して追記してください。
kuma903

2019/11/28 10:20

回答ありがとうございます。 サンプルコードを確認させて頂きました。 「Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\kaihatu\tes.php on line 13」 とforeachの部分でエラーが起きている様です。 また、json_last_errorを$listに充ててみたところ「Warning: json_last_error() expects exactly 0 parameters, 1 given in C:\xampp\htdocs\kaihatu\tes.php on line 10」が表示され、var_dumpにはNULLが表示されます。 PHPを触って半年しか経たないため私で分かる範囲、上記の方法で考えましたが分かりません。 ご教授いただければ幸いです。
退会済みユーザー

退会済みユーザー

2019/11/28 10:51

手元で動かしたサンプルコードなので、 全く動かないってことはないはずです。 コード枠右上にある「+」みたいなところでコードを全文コピーできますので、 差し支えない別なファイルに保存してみてください。 (ただしBOMなしUTF-8、改行コードはLFオンリーでね。)
kuma903

2019/11/28 11:47 編集

返信ありがとうございます。 再度コピーしUTF-8でLFオンリーで確認しましたが、 「Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\kaihatu\tes.php on line 10」 というエラーが発生しました。 やはりforeachで起きている様なので一度ダウンロードしたJSONとURLのコメントを外してテストを行いましたがエラーの様です。 もう少し私の方でやれそうな部分を探してみますがもしお気づきの点がありましたらご教授いただければ幸いです。 追記・報告 XAMPP v3.2.1で表示した際は上記の通り、エラーの表示がありましたが、lolipopサーバに入れたところエラーは表示されませんが、なにも表示されていない状態です。 また進捗がありましたら報告致します。
退会済みユーザー

退会済みユーザー

2019/11/28 12:55

改めて動作確認を取ってから掲載し直します。
退会済みユーザー

退会済みユーザー

2019/11/28 13:29

ネット上の、JSON整形サービスを使って整形後であれば、json_decode()にてSyntax Errorを出すことはないのですが、直接該当jsonを読み込むとダメですね。引き続き調査してみます。
退会済みユーザー

退会済みユーザー

2019/11/28 14:00

マルチバイトがエンコードされていませんね、このJSONファイル。
退会済みユーザー

退会済みユーザー

2019/11/28 14:02

UTF-8だけどBOM付きでした。なんと。
退会済みユーザー

退会済みユーザー

2019/11/28 14:05

BOM除去すると、エンコードは通るけど、マルチバイトの文字列が取得できないですね。
退会済みユーザー

退会済みユーザー

2019/11/28 14:08

直したコードで、ひとまず書籍タイトルはずらりと表示できたので、問題ないかと思ったのですががが。
退会済みユーザー

退会済みユーザー

2019/11/28 14:11

こっちのコードが間違えてました。
退会済みユーザー

退会済みユーザー

2019/11/28 14:13

チェックしていただきありがたいです。
退会済みユーザー

退会済みユーザー

2019/11/28 14:24

いえいえ。
kuma903

2019/11/28 14:34

お二方、返信ありがとうございます。 また、返信が遅れてしまい申し訳ありません。 サンプルコードを確認させて頂きました。 私の環境で動作を確認しました。 皆様のおかげで私のやりたいアプリを開発することができます。 後学のため、今回のエラーの原因についてお聞きしたいのですが、 ・UTF-8のBOMあり ・JSONファイルにゴミが入っていた ・正規のAPIではないためサポートがしっかりしていない 以上、3点から私の直面したASCIIになってしまうという現象などが起きていたということでよろしいでしょうか。 本当にありがとうございました。
退会済みユーザー

退会済みユーザー

2019/11/29 01:07

わかってしまえば簡単なことですが、 UTF-8エンコーディングのBOM(バイトオーダーマーク)付きということを踏まえて、 データの先頭にあるBOMの3バイトを削除してしまえば json_decode()で処理できます、という内容でした。 あと、この手のjsonファイル提供APIは内容の更新頻度を踏まえて、 ページを表示するたびに都度先方のサーバーに取得しに行くと負担をかけてしまうため、 数時間(あるいは一日)に一度取得して自分のところにキャッシュしておくような使い方がよろしいかと思います。 正規のAPIではないことから、いつ情報提供が終わってもおかしくありませんし、 どう使えばいいのか教えてもらえるものでもないでしょうから。
kuma903

2019/11/29 02:36

なるほど。 BOMの3バイトが邪魔をしていたという事ですね。 JSONについてはレスポンスも悪いため今のところcoronを利用し、できるだけ負荷をかけないようにする予定です。 正規のAPIが出てくれればいいのですが、探したところ見つからずこちらの非公式APIを利用する形となりました。 (TRCがオープンデータを出していますが更新頻度と形式があまりに使いにくいため除外しました。) m6u様やKosuke_Shibuya様、皆様のお力添えいただいたおかげで開発が進みます。 ありがとうございました。
guest

0

mb_convert_encoding ( string $str , string $to_encoding [, mixed $from_encoding = mb_internal_encoding() ] ) : string は、文字列の文字コードを $from_encoding から $to_encoding に変換する関数です。
PHP: mb_convert_encoding - Manual

ご指定のコードはもとがASCIIでUTF-8に変換しようとしています。ダウンロードしたjsonファイルがUTF-8なのであれば、もともとUTF-8なのでやる意味がないです。あと、そもそも 'UTF8' はありません。

投稿2019/11/28 09:30

thyda.eiqau

総合スコア2982

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

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

kuma903

2019/11/28 10:37

回答ありがとうございます。 初心者で至らない点ばかりです。 勉強になります。 皆様からご教授頂いた点は修訂正させて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問