PHPでXMLを引っ張ってきてそれを連想配列化したい!

数多あるソーシャルサービス。
それと連携したウェブページやウェブサービスを作れたら面白いですよね?
そんなソーシャルサービスの記録しているデータこそが今まさに注目のキーワードの「ビッグデータ」!!

そこで、ソーシャルサービスと連携したものを作るとき、
ソーシャルサービスが提供するビッグデータを取得するためにAPIというものにアクセスしてデータを取得します。

そのデータ形式は大きく分けて2つ!
・XML
・JSON
です。

今回はPHPでXMLを取得して、PHP内で扱えるように連想配列にして変数に定義するやり方について紹介します。

スポンサード リンク

simplexml_load_file でXMLデータをゲットだぜ!

simplexml_load_file
という関数を使います。
コイツはXMLを取得する関数です!

試しにこのブログのRSS(XML形式)を読んでみますか。
http://cafe.76bit.com/feed/


<?php

$rss =  'http://cafe.76bit.com/feed/';
$xml = simplexml_load_file($rss);
var_dump($xml);

?>

実行すると・・・、
http://cafe.76bit.com/sample/php/gettingXML.php

ドバーーーーっとデータの洪水ですねw
まさにビッグデータ!!

あとはゲットしたXMLを格納した配列「$xml」から必要な情報を抜き取れれば目的達成ですね!

get_object_vars で取得したXMLを配列に変換せよ!

あれ?さっき「simplexml_load_file」で取得したのって配列になっていないの?
そう思いますよね?diceも配列に見えました。

配列だと思って $xml から必要データを抽出するためにforeachかましたら・・・、

Warning: Invalid argument supplied for foreach()

というエラーがでて困っていました。
調べると、「simplexml_load_file」で取得したデータは配列に見えて配列ではないんです!
というわけで配列に変換してあげないといけません。

そこで「get_object_vars」です。
さっきのプログラムに付け足すと


<?php

$rss =  'http://cafe.76bit.com/feed/';
$xml = simplexml_load_file($rss);
$data = get_object_vars($xml);
var_dump($data);

?>

実行すると・・・、
http://cafe.76bit.com/sample/php/gettingXML2.php

頭にarrayとあり少し違いますね?これで配列になりました!
それでは自分の使いたい要素を抜き出す方法を解説します!

とりあえず取得したデータからタイトルだけ抜き取り表示させてみる

$data から記事タイトルを抜き出し、


<ul>
<li>記事タイトル1</li>
<li>記事タイトル1</li>
・
・
・
<li>記事タイトルn</li>
</ul>

のようなhtml化にしてみましょう!

配列の定義のされ方をチェック

先ほど var_dump($xml) の表示結果から
1つ目の記事を引っこ抜きインデントしてみました。

array(2) { 
  ["@attributes"]=> array(1) { 
    ["version"]=> string(3) "2.0"
   } 
  ["channel"]=> object(SimpleXMLElement)#2 (7) { 
    ["title"]=> string(10) "76bit Cafe" 
    ["link"]=> string(21) "http://cafe.76bit.com" 
    ["description"]=> string(39) "日々クリエイティブな日常を" 
    ["lastBuildDate"]=> string(31) "Wed, 23 Oct 2013 07:24:08 +0000" 
    ["language"]=> string(2) "ja" 
    ["generator"]=> string(29) "http://wordpress.org/?v=3.6.1" 
    ["item"]=> array(20) { 
      [0]=> object(SimpleXMLElement)#3 (7) { 
        ["title"]=> string(42) "PHPのバージョンを確認したい!" 
        ["link"]=> string(63) "http://cafe.76bit.com/web/php-db/how-to-check-your-php-version/" 
        ["comments"]=> string(72) "http://cafe.76bit.com/web/php-db/how-to-check-your-php-version/#comments" 
        ["pubDate"]=> string(31) "Wed, 23 Oct 2013 07:21:07 +0000" 
        ["category"]=> array(4) { 
          [0]=> object(SimpleXMLElement)#23 (0) { } 
          [1]=> object(SimpleXMLElement)#24 (0) { } 
          [2]=> object(SimpleXMLElement)#25 (0) { } 
          [3]=> object(SimpleXMLElement)#26 (0) { } 
        } 
        ["guid"]=> string(28) "http://cafe.76bit.com/?p=657" 
        ["description"]=> object(SimpleXMLElement)#27 (0) { } 
      } 

      [1]=> object(SimpleXMLElement)#4 (7) { 
        ["title"]=> string(104) "Illustratorで自分の狙ったレイヤーにペーストができないのをなんとかしたい!" 
・
・
・

となります。
改行とインデントを加えて自分が見やすいようにして解析してみてください!
これは色々なソーシャルサービスでも同じです。

抜き取ったデータはいったいどのような引き出しに収納しているのか?
生データをテキストエディタにコピペして自分なりに階層構造を解析しましょう!

array
 |-["@attributes"]
 |  |-["version"]
 |-["channel"]
    |-["title"]
    |-["link"]
    |-["description"]
    |-["lastBuildDate"]
    |-["language"]
    |-["generator"]
    |-["item"]
       |-[0]
       | |-["title"]←コレを取得したい!
       | |-["link"]
       | |-["comments"] 
       | |-["pubDate"]
       | |-["category"]
       | |  |-[0]
       | |  |-[1]
       | |  |-[2]
       | |  |-[3]
       | |-["guid"]
       | |-["description"]
       |
       |-[1]
       | |-["title"]←コレを取得したい!
       | |-["link"]
         ・
         ・
         ・

foreach で配列から任意のデータを抽出する

このRSSは20件の記事があります。
1件ずつ抜き出すのはメンドウですよね?
こういときは foreach という、配列のための繰り返し処理をしてくれる関数を使いましょう!
それでは「title」要素だけを抜き出してみましょう!

配列とオブジェクトの混在の落とし穴!


foreach ($data['channel']['item'] as $key => $val) {
	echo '<li>' . $val['title'] . '</li>';
}

とすると、見事に・・・、

Warning: Invalid argument supplied for foreach()

エラーorz
今回はちゃんと配列に変換したのに・・・。

どうやら指定の仕方がまずかったようです。
先ほどのvar_dump($data)の結果を見ると

・ルートは array(2)
・[“channel”]=> object(SimpleXMLElement)#2 (7)
・[“item”]=> array(20)

何!?「channel」だけarray(配列)じゃなくobject(オブジェクト)と出ています!
[‘channel’][‘item’]というのは配列の指定の仕方で「item」はオブジェクトの一つな分けです。
なので、

[‘channel’]->item

と指定してあげればいいのです!
・・・。

「スーパー ウルトラ グレート デリシャス ワンダフル
             ワカリヅレェェェーー(゚∀゚)ーー!」

いよいよforeach で配列から任意のデータを抽出する

あと、「item」で定義されている単一記事の要素も配列じゃなくオブジェクトですね。気をつけましょう!
([0]=> object(SimpleXMLElement)#3 (7))

以上を踏まえて、ようやく完成しました!!


<?php

$rss =  'http://cafe.76bit.com/feed/';
$xml = simplexml_load_file($rss);
$data = get_object_vars($xml);

echo '<!doctype html>';
echo '<html lang="ja">';
echo '<head>';
echo '<meta charset="utf-8">';
echo '</head>';
echo '<body>';
echo '<ul>';

foreach ($data['channel']->item as $item) {
	echo '<li>' . $item->title . '</li>';
}

echo '</ul>';
echo '</body>';
echo '</html>';

?>

実行すると・・・、
http://cafe.76bit.com/sample/php/gettingXML3.php

これでXML形式であればPHPに取り込んで自由にデータを扱うことができるようになりました。
みなさんもブログやTwitterやLast.fmやflickrやAmazonなどのAPIを使って面白いウェブアプリやマッシュアップを作ってみてください!

diceは目下Last.fmのAPIとAmazonのマッシュアップ的なランキングサイトを作っております。完成したらこのブログで報告します!
それでは!!

コメント

Facebookコメント

※コメントしたけど表示されてない方へ

パーマリンクを変えてしまったおかげで表示されなくなってしまいました。
折角コメントいただいたのにスイマセンm(__)m
パーマリンク変更しても何とか表示できる方法を現在模索中です。

“Facebookコメント”じゃないコメントを残す

このコメント欄は一時的に且つ試験的に復活させ実装させています。スパムが増加すると廃止します。なのでできるだけFacebookのコメントでコメントをお願いします。m(__)m
なお、メールアドレスは公開されることはありません。

  1. hoge さんのコメント

    古い記事にコメント付けてすみません。
    この記事助かりましたので、お礼かたがたタイポっておりましたのでご指摘。

    「foreach で配列から任意のデータを抽出する」
    …こういときは forreach という…

    forreach
    foreach

    (・ω・)ノシ

    • dice さんのコメント

      誤植の指摘ありがとうございます!修正しました。

コメントを残す