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

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

ただいまの
回答率

89.10%

楽天APIで取得した配列から必要な情報を取り出したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 224

takato.work

score 8

前提・実現したいこと

楽天APIを使い、商品検索して帰ってきた値を取得したいのですが、PHPのjson_decodeで配列化したjsonデータからfor分などの繰り返し処理でデータを取りたいです。

発生している問題

for文で値を取ろうとすると失敗する。エラーコードはなく、一つ目以降出力がされなかった。

公式ドキュメント

https://webservice.rakuten.co.jp/api/ichibaitemsearch/#requestURL

該当のソースコード

$json = file_get_contents("https://app.rakuten.co.jp/serv........")
$arr = json_decode($json, true);

print($arr['Items'][1]['Item']['affiliateUrl'].'<br><br>');
print($arr['Items'][2]['Item']['affiliateUrl'].'<br><br>');
print($arr['Items'][3]['Item']['affiliateUrl'].'<br><br>');
print($arr['Items'][4]['Item']['affiliateUrl'].'<br><br>');
print($arr['Items'][5]['Item']['affiliateUrl'].'<br><br>');
print($arr['Items'][6]['Item']['affiliateUrl'].'<br><br>');
print($arr['Items'][7]['Item']['affiliateUrl'].'<br><br>');


下はvar_damp($arr)によって出力された配列です。

array(10) {
  ["Items"]=>
  array(30) {
    [0]=>
    array(1) {
      ["Item"]=>
      array(35) {
        ["mediumImageUrls"]=>
        array(3) {
          [0]=>
          array(1) {
            ["imageUrl"]=>
            string(100) "https://thumbnail.image.rakuten.co.jp/@0_mall/eikoshop11/cabinet/zg0982020/zg098-01n.jpg?_ex=128x128"
          }
          [1]=>
          array(1) {
            ["imageUrl"]=>
            string(99) "https://thumbnail.image.rakuten.co.jp/@0_mall/eikoshop11/cabinet/zg0982020/zg098-02.jpg?_ex=128x128"
          }
          [2]=>
          array(1) {
            ["imageUrl"]=>
            string(101) "https://thumbnail.image.rakuten.co.jp/@0_mall/eikoshop11/cabinet/zg0982020/zg098-03-1.jpg?_ex=128x128"
          }
        }
        ["pointRate"]=>
        int(1)
        ["shopOfTheYearFlag"]=>
        int(0)
        ["affiliateRate"]=>
        int(2)
        ["shipOverseasFlag"]=>
        int(0)
        ["asurakuFlag"]=>
        int(1)
        ["endTime"]=>
        string(0) ""
        ["taxFlag"]=>
        int(0)
        ["startTime"]=>
        string(0) ""
        ["itemCaption"]=>
        string(1915) "商品名 送料無料モバイルバッテリー大容量10000mAh iPhone&Android両方対応極薄軽量ケーブル内蔵型6色iPhone8 iPhoneX iPhone7 Plus アイフォン7 iPhone6 plus iPhone6 iPhone6s plus iPhone5 SE携帯充電器4台同時充電可能 特徴 バッテリー容量:10000mAh 出力電圧:DC5V/2.4A 入力電圧:DC5V/2A 重量:210g サイズ:135*70*128mm 適応機器:iPhone8 iPhoneX iPhone7 &nbsp; iPhone6/6S/plus&nbsp; iPad Andriod機種など 充電回数:3.5回 付属品ケーブル カラー カラー:6色(グレー、ゴールド、ホワイト、ピング、ブルー、ブラック) 生産国 中国 ●2019年4月1日Type-C内臓ケーブルを追加いたしました。エクスペリアType-Bに対応しておりません。 ご注意 ●商品の色見はご覧のパソコンの環境により、実物と多少異なって見える場合がございますのでご了承ください。 ●ご注文いただきました商品であっても品切れの場合がございますのでご了承ください。その場合はメールにておしらせいたします。 ●ポーチは色落ち可能性ございますので、ご使用の際はご注意ください。尚、サービスポーチついての色落ち等の対応はしておりません。モバイルバッテリー 10000mAh大容量 極薄軽量  6色 バッテリー容量:10000mAh 出力電圧:DC5V/2.4A 入力電圧:DC5V/2A 重量:210g カラー:6色(グレー、ゴールド、ホワイト、ピング、ブルー、ブラック) サイズ:135*70*128mm 適応機器:iPhone8 iPhoneX iPhone7 iPhone6/6S/plus iPhone5/SE ipad Andriod機種など 充電回数:3.5回 付属品:ケーブル ●2019年4月1日Type-C内臓ケーブルを追加いたしました。 同梱おすすめ 同梱おすすめ 1280円(税込/送料無料) 1,480円(税込/送料無料)"
        ["catchcopy"]=>
        string(93) "防災 ギフトiPhone&Android&Typec対応 2.4A 登山 キャンプ 外出 機内持ち込み"
        ["tagIds"]=>
        array(10) {
          [0]=>
          int(1000873)
          [1]=>
          int(1000876)
          [2]=>
          int(1000880)
          [3]=>
          int(1000881)
          [4]=>
          int(1000885)
          [5]=>
          int(1000886)
          [6]=>
          int(1002891)
          [7]=>
          int(1005126)
          [8]=>
          int(1016358)
          [9]=>
          int(1019017)
        }
        ["smallImageUrls"]=>
        array(3) {
          [0]=>
          array(1) {
            ["imageUrl"]=>
            string(98) "https://thumbnail.image.rakuten.co.jp/@0_mall/eikoshop11/cabinet/zg0982020/zg098-01n.jpg?_ex=64x64"
          }
          [1]=>
          array(1) {
            ["imageUrl"]=>
            string(97) "https://thumbnail.image.rakuten.co.jp/@0_mall/eikoshop11/cabinet/zg0982020/zg098-02.jpg?_ex=64x64"
          }
          [2]=>
          array(1) {
            ["imageUrl"]=>
            string(99) "https://thumbnail.image.rakuten.co.jp/@0_mall/eikoshop11/cabinet/zg0982020/zg098-03-1.jpg?_ex=64x64"
          }
        }
        ["asurakuClosingTime"]=>
        string(5) "12:00"
        ["imageFlag"]=>
        int(1)
        ["availability"]=>
        int(1)
        ["shopAffiliateUrl"]=>
        string(167) "https://hb.afl.rakuten.co.jp/hgc.........."
        ["itemCode"]=>
        string(19) "eikoshop11:10000058"
        ["postageFlag"]=>
        int(0)
        ["itemName"]=>
        string(314) "【バッテリーポーチプレゼント中&3種類ケーブル内蔵】 モバイルバッテリー 大容量 Typec 充電器ケーブル内蔵型 極薄軽量10000mAhiPhone &Android&Type-Cすべて対応 プレゼントiPhone11 iPhonexs iPhonexsm iPhone8 iPhoneXiPhone7 Plus iPhone64台同時充電可能"
        ["itemPrice"]=>
        int(1380)
        ["pointRateEndTime"]=>
        string(0) ""
        ["shopCode"]=>
        string(10) "eikoshop11"
        ["affiliateUrl"]=>
        string(191) "https://hb.afl.rakuten.co.jp/hgc............"
        ["giftFlag"]=>
        int(0)
        ["shopName"]=>
        string(13) "エイコShop"
        ["reviewCount"]=>
        int(4969)
        ["asurakuArea"]=>
        string(385) "群馬県/埼玉県/千葉県/東京都/神奈川県/新潟県/富山県/石川県/福井県/山梨県/青森県/長野県/岐阜県/静岡県/愛知県/三重県/滋賀県/京都府/大阪府/兵庫県/奈良県/岩手県/和歌山県/鳥取県/島根県/岡山県/広島県/山口県/徳島県/香川県/愛媛県/高知県/宮城県/秋田県/山形県/福島県/茨城県/栃木県"
        ["shopUrl"]=>
        string(167) "https://hb.afl.rakuten.co.jp/hgc............"
        ["creditCardFlag"]=>
        int(1)
        ["reviewAverage"]=>
        float(4.22)
        ["shipOverseasArea"]=>
        string(0) ""
        ["genreId"]=>
        string(6) "564277"
        ["pointRateStartTime"]=>
        string(0) ""
        ["itemUrl"]=>
        string(191) "https://hb.afl.rakuten.co.jp/hgc..............."
      }
    }
    [1]=>
    array(1) {
      ["Item"]=>
      array(35) {
      }
    }.....

試したこと

['Items']の後の整数が入っいている[]に$iを渡し、for文による繰り返し構文で$iに1〜20までの数字を渡したのですが、最初のURL以降は取得できませんでした。
for文が機能していないのではと、「echo $i」も行いましたが、こちらは正常に1〜20を出力しました。

for($i=0; $i<20; $i++;) {
  print($arr['Items'][$i]['Item']['affiliateUrl'].'<br><br>');
  echo $i;
}


foreachによる繰り返し処理も試しましたが、うまくいきませんでした。試したコードは下記です。

foreach($arr['Items'] as $value){
    print($key);
    print($value);
}


結果
ArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArray

foreach($arr['Items'] as $key => $value){
    print($key);
    print($value);
}


結果
0Array1Array2Array3Array4Array5Array6Array7Array8Array9Array10Array11Array12Array13Array..........

その他やりたいこと

もしできれば、affiliateURL以外の値も取得したいのでその方法と、上記のコードでは「print」で出力していますが、実際の環境では変数に置くなどして,htmlとcssで整形もしていきたいので、その方法まで教えていただけると幸いです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2020/07/01 06:26

    forでどのように書いたのでしょうか

    キャンセル

  • m.ts10806

    2020/07/01 06:29

    取得したJsonの内容が提示されていないため、他者には検証が不可能である=「こんな感じで組む」程度しかアドバイスができないことも了承ください。(公式のAPIなので、全く見せられないということはないでしょうけど…)
    APIの返却値の例が記載された記事やドキュメントのURLもご提示ください

    キャンセル

  • takato.work

    2020/07/01 10:14

    ご回答ありがとうございます。アドバイスの通り、実際に書いたfor文とJsonを配列化したものを「var_damp」で出力したものの一部を追記しました。
    ありがとうございます。

    キャンセル

回答 2

+3

多少ループがネストしても、$arr['Items']自体をforeachで回していったほうが良いように思います。
0~20を固定で回すと、キーがないときに配列のキー参照のエラーになりますし。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/01 11:45

    手始めとしては間違ってません。
    回答冒頭にかいたように「ループを重ねる」です。
    Arrayがでるということは配列がとれてるということなので$valueもループさせるか、配下のキーが全て同じ構成であれば$value[キー名]でキーをたどっていきます

    キャンセル

  • 2020/07/01 13:26

    ご回答頂きありがとうございます。
    おふた方ともにとても参考にさせて頂きましたが、別の回答者様がより具体的に説明をしてくださったので恐れながら今回はそちらの方をベストアンサーとさせていただきます。

    キャンセル

  • 2020/07/01 13:56 編集

    やはり配列参照とデバッグのしかたを確実におさえられたほうがこの先困らなくて済みます。
    今回に特化したやり方を覚えても、今後少し構造が変わるとまた質問する羽目になりそうですし。

    キャンセル

checkベストアンサー

+1

多次元の配列をforeachで走査する場合、
foreachの中で要素に対してforeachを実行する必要があります。

foreach($arr['Items'] as $key => $value){
    print($key);
    print($value);
}


であれば

foreach($arr['Items'] as $key => $value){
    var_dump($key);
    foreach($value as $k => $v){
        var_dump($k);
        //$vが配列の場合はさらにforeachをする必要があるので、is_array($v)等で判定して処理をわける
        var_dump($v);
    }
}


みたいな感じです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/01 13:23

    ご丁寧に説明していただきありがとうございます。

    foreach($arr['Items'] as $value){
    foreach ($value as $key => $v) {
       print($v['affiliateUrl']);
    echo '<br><br>';
    }
    }

    この記述により「前提、実現したいこと」の記述と同じことができました。また、$v[smallimg]などは更に配列になっているのでその場合はforeachをかけて取り出そうと思います。

    また、これで得る事のできた値(今回はURL)を変数などに入れてそれぞれ取り出したい場合、どの様に記述すればよいでしょうか。
    実現させたいことは、商品情報を検索によって一覧で取得した後、任意の商品画像をクリックすると「affiliateUrl」をゲットできるという仕組みを作ろうと考えています。
    単に「$affiliateUrl」のような変数に渡しても、更新されてしまうのでなにか適切な方法などありましたらご教授いただけると嬉しいです。

    だいぶ抽象的な質問になってしまっているので、簡単なヒントやアドバイスをいただけたらと思います。

    キャンセル

  • 2020/07/01 14:10

    「affiliateUrl」をゲットできる
    というのが具体的にどういう挙動かはわかりませんが、
    商品画像をクリックして画面遷移させずに何かをしたいという話だと、JavaScriptとの連携が必要になりますね。
    方向性としては、
    そのHTML要素の中に、$affiliateUrをデータとして出力しておく
    クリックしたタイミングでJavaScriptで取得して処理する
    という感じになります。

    この辺りは全部一気にやろうとしても難しいので、
    1. まずは画面側で理想的なHTMLとJavaScriptを作る

    2. それをPHPで出力する方法を考えてやってみる

    3. APIの仕様上難しければ、HTML側の構造を変更する

    というのを繰り返しトライしてみてください。

    キャンセル

  • 2020/07/01 14:12

    わかりました頑張って作ってみます。
    本題の質問とはずれたところまで丁寧に説明して頂きありがとうございました。
    ベストアンサーとさせて頂きました。

    キャンセル

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

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる