XMLを使って遊ぼう! ITかあさん

ITかあさん

PHPの配列で遊んでみる

RSSをもっと見やすく表示したい!

前回の記事でRSSをsimplexml_load_string関数を使ってRSSのXMLを表示してみました。でも、ちょっと見にくいし、分かりずらいので、自由に自分のほしいデータを持ってこれるように 配列構造を変更して、より配列に慣れ親しんでいこうと思います。
配列が分かればPHPが分かります。
ずばり、

配列を制するものは配列を制す!

です。

RSSを通常の配列の形に

前回の記事の最後の方にちょっとxmlオブジェクトのままだと扱いにくい点に触れましたが、
それならば扱いやすい配列の形に変換すればいいんです。
最初の2つのxmlオブジェクトとして展開するまでは前回と何も変わっていまん。
少し変わったのが、そのまま$xml->channel->item->$i->title;をechoで出力せず、
一度$rss[$i][‘title’]に代入してあげている点です。

連想配列に変換

実際に連想配列にする処理は以下。とってもシンプルですね。

//フィードを取得したいRSSのURLを記述
$contents = file_get_contents('http://www.kaasan.info/feed');
//XMLをオブジェクトに変換
$xml = simplexml_load_string($contents);
//連想配列作成用に、新規で空の配列を用意する
$rss = array();
for ($i = 0; $i <= 9; $i++) {
$rss[$i]['title'] = (string)$xml->channel->item->$i->title;
$rss[$i]['description'] = (string)$xml->channel->item->$i->description;
$rss[$i]['date'] = (string)$xml->channel->item->$i->pubDate;
$rss[$i]['link'] = (string)$xml->channel->item->$i->link;
}

解説

for文のループについては前回の記事を参考にしてもらうとして、大事なのが2つ。

・新規に配列を作る時は空の配列を用意する
・代入するxmlオブジェクトを(string) string(文字列)指定にする

まず配列とは、タンスのイメージです。
引き出しの中にデータが入ります。
ただの変数では引き出しがありません。
引き出しが無いなら空の配列を代入することで新たに引き出しを作ってあげればいいんですね。
たったコレだけ空の配列が出来、配列として代入することが出来るのです。
新たに配列を作りたいときには有効ですのでぜひ覚えて下さい。
RSSの配列代入イメージ

作った配列を出力してみる

作った配列をprint_rして出力してみましょう。
実行例
RSSをそのまま出力したものと比べるとぐっと見やすくなったのが分かりますか?
RSSをそのまま出力
$rssの出力
今まではrssの情報をすべて出力していましたが、今回新規で作った配列$rssは必要な部分だけ選んで配列化していますから、
とても見やすいですね。

RSSをHTMLの中に出力

最後の仕上げです。作った$rssをHTMLの中に書いて、きれいにRSSを表示してみましょう!
今回は非常に簡単だったのでループをもう一つ新しいものを覚えておきましょう。
foreach文です。

foreach文

for文は

for ($i = 0; $i <= 9; $i++){
echo ‘hogehoge';
}

としたように、$iがいくつから始まり,いくつまで繰り返すかを必ず指定しなければなりませんでしたが、
foreachはfor文と違い、問答無用で配列のある文だけループします。
たったこれだけです。初心者にはfor文が直感的で分かりやすいという意見もありますが、
PHPではforeachの方がやや実行が早いというメリットもありますので
for文の特性を利用した『配列中の何番目から何番目!』という決まりが無く、配列全て出力するのであればforeachを使うのがよいでしょう。

foreach($rss as $val)となっていたら、$valにデータを代入しているようなイメージでいてください。

foreachでの実行例

<dl>
<?php foreach($rss as $val):?>
<dt>
<a href="<?php echo $val['title'];?>">
タイトル:<?php echo $val['title'];?></a>
</dt>
<dd>ディスクリプション:<?php echo $val['description'];?></dd>
<dd>日付:<?php echo $val['date'];?></dd>
<?php endforeach;?>
</dl>

またはこんな書き方も出来ます。

<dl>
<?php foreach($rss as $val){ ?>

<dt><a href="<?php echo $val['title'];?>">タイトル:<?php echo $val['title'];?></a></dt>
<dd>ディスクリプション:<?php echo $val['description'];?></dd>
<dd>日付:<?php echo $val['date'];?></dd>
<?php } ?>
</dl>

ただ、これでは実際に } 閉じるタグがfor文の閉じタグなのかforeachの閉じタグなのかどちらなのか分からりにくいので個人的には上の方をオススメします。

これは何回目のループなのかを出したいなら

これは何回目のループなのかを出力したいなら、キー名の出力の仕方を覚えるとよいです。

<dl>
<?php foreach($rss as $key => $val):?>
<dt>第<?php echo $key;?>回目</dt>
<dt><a href="<?php echo $val['title'];?>">タイトル:<?php echo $val['title'];?></a></dt>
<dd>ディスクリプション:<?php echo $val['description'];?></dd>
<dd>日付:<?php echo $val['date'];?></dd>
<?php endforeach;?>
</dl>

実行例
以上でRSSの出力についてはおしまいです!

XMLとは?

2012年02月12日に開催したLinuxお勉強しよう会でPHPとXMLを使って遊ぼうというネタを紹介させて頂きました。
そこでのネタの詳しい解説としてまずはXMLとは何か?という根本的なところから初めていきます。

XMLとは?

XMLとは『コンピューターが認識するためのことば』です。
例えばHTMLはあくまでも人間が目で見て『これは何だ』と認識するものですが、コンピューターはHTMLを見ても内容を解析することは出来ません。
そこでXMLを利用するわけです。

XMLが利用されているところ

XMLの代表的な例はRSSがあります。
RSSとはブログなどの更新情報を配信などをしているところです。
RSSが配信されているサイトだと(このITかあさんのブログもRSSが配信されているのですが)このようにURLのアドレスバーにアイコンが表示されます
RSSが配信されているサイトのアドレスバー

ブラウザによって表示に誤差があるもののRSSをブラウザによって表示すると以下の画像のような表示になるかと思います。

このRSSをリーダーを使って購読するとこのようになります。
RSSをGoogleリーダーで購読した時の様子

RSSが配信されることのメリット

HTMLそのままだとレイアウトを変更するなりして、自分のサイトの一部分に組み込んだりすることは難しいですが、
RSSを配信することのメリットはGoogleリーダーで読み込んだり、自分のブログなどに設置して2次利用しやすくなります。
日本人はよほどIT企業に勤めていたりでもしなければRSSを購読してブログやサイトの更新情報をチェックする人は少ないかもしれません。しかもたくさんの人に購読されたからと言ってSEOに効果があるわけでもありません。
しかし、RSSはXMLという言語で作られているのでちょっとPHPをかじったレベルの人であればいとも簡単に自分のサイト内に表示させることが出来ます。
RSSというXML言語で作られたものを配信することによって誰かに2次利用してもらえることが期待出来、最終的にはめぐりめぐって自分のサイトのSEOに繋がるかもしれません。
そんなわけでPHPとXMLを使ったおもしろくて実用的なコンテンツの作り方を学びたいと思います。

RSSを自分のサイトに表示させる

PHPを使ってRSSを自分のサイトの好きなところに表示させてみよう

PHPを使ってRSSを自分のサイトやブログの好きなところに表示させてみたいと思います。
RSSはXMLという言語を使って出来ています。XMLについての詳しい解説はこちらを確認して下さい。

RSSをXMLとして表示する

RSSを表示してあげるには、
1.表示したいRSSのURLを指定するfile_get_contents関数
2.XMLとして開く関数を実行するsimplexml_load_string関数

$contents = file_get_contents('http://www.kaasan.info/feed');
$xml = simplexml_load_string($contents);

なんと、たったのこれだけで準備は完了です。
$xmlの中身がどうなっているのか、念のために参照してみます。
一つの変数($なんちゃら)に複数の値が入っているデータを配列をいうのですが、この配列構造になっているデータを参照するのに使う関数がprint_rまたはvar_dumpです。私も日ごろPHPで何かプログラミングをしていて、一番お世話になっている関数です。

$contents = file_get_contents('http://www.kaasan.info/feed');
$xml = simplexml_load_string($contents);
//$xmlの中身を参照。preタグで囲うと見やすくなる。
echo '<pre>';
print_r($xml);
echo '</pre>';

$xmlの中身を参照した時の実行結果

もしかしたらこの画面を見たことのある人もいるかもしれません。よくこれだけで『エラーです!どうにかしてください!』といわれるんですが、『あ、これ今デバック中なので・・・・』みたいなやりとりをよくWEBデザイナーの方としていますw
実はこの時点ですでにRSSをHTML内に表示する準備は出来ているんです。
細かい解説は後にして、ひとまず表示だけ先にしたいと思います。

HTML内にRSSを表示してみる

<dl>
<?php for($i = 0; $i <= 9; $i++):?>
<dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt>
<dd><?php echo $xml->channel->item->$i->description;?></dd>
<dd><?php echo $xml->channel->item->$i->pubDate;?></dd>
<?php endfor;?>
</dl>

実行結果

RSS表示の仕組みを解説

この画像は$xml->channel->itemの中身です。RSSの中身をprint_rしているURLと合わせて確認して下さい。
print_rで$xmlの中身を参照したとき、RSSをURLで確認して、件数を一つずつ数えると10件ありますが
PHPやJavascriptなどプログラミング言語では配列のカウントは0から数えるという大事な決まりごとがあります。

http://kaasan.biz/print_r.phpの参照

RSSをprint_rの参照結果

$xml->channel->itemの中身

$xml->channel->itemの中身

for文のループの仕組み

$xml->channel->itemの中身は分かっても、それがどういう仕組みでループされているかがピンと来ないかもしれません。私も生まれて初めてPHPでループをした時はピンときませんでした。

$iを出力してみる

そこで$iを出力しながら実行してみましょう。

<dl>
<?php for($i = 0; $i <= 9; $i++):?>
<dt>第<?php echo $i;?>番目のループ</dt>
<dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt>
<dd><?php echo $xml->channel->item->$i->description;?></dd>
<dd><?php echo $xml->channel->item->$i->pubDate;?></dd>
<?php endfor;?>
</dl>

実行結果

$xmlをprint_rで参照したものと、比べてみる

$xmlをprint_rで参照したものと、RSSの実行2を比べてみましょう。
$iには数字が1ずつ増加していることが2つを比べると理解できると思います。

好きなところだけ表示するには?

応用編として、好きなところだけを表示したいとします。例えば3番目から6番目。
(プログラム上、配列は0番目からカウントするのをお忘れなく)
for内の数字を変更すればいいだけです。

<dl>
<?php for($i = 3; $i <= 6; $i++):?>
<dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt>
<dd><?php echo $xml->channel->item->$i->description;?></dd>
<dd><?php echo $xml->channel->item->$i->pubDate;?></dd>
<?php endfor;?>
</dl>

逆順にしてみる

逆順にする方法もあります。配列の順番を入れ替える関数もあるんですが、もっと簡単に。
$i++で1ずつ増えるので$i–で1ずつマイナスにする方法もあるんです。
こうすればさっきと逆順になりますね!

//10番目から1ずつマイナスに
<dl>
<?php for($i = 9; $i <= 0; $i--):?>
<dt><a href="<?php echo $xml->channel->item->$i->link;?>" target="_blank"><?php echo $xml->channel->item->$i->title;?></a></dt>
<dd><?php echo $xml->channel->item->$i->description;?></dd>
<dd><?php echo $xml->channel->item->$i->pubDate;?></dd>
<?php endfor;?>
</dl>

最新1件だけ表示するには?

ループしないで最新1件だけがほしい!1件だけならループの必要がない?
最新1件だけのタイトルだけを出力するとして・・・

<?php echo $xml->channel->item->0->title;?>

どうでしょう?エラーですね。$ループされていたとき$inには数字が入っていたのだから、そのまま数字を書けばいいんじゃないの?
と思ってしまいますよね。これはちょっとした落とし穴でして。

->はオブジェクト(クラス)のメソッドやフィールド変数を参照するための演算子

演算子って言われてもイマイチピンときませんが、数字はあくまでも数字であることは分かりますよね。数字は数字。それ以上参照のしようがありませんものね。
オブジェクトでもなんでもないただの数字を展開しようとしたのでここではエラーになってしまったのです。
ちょっと面倒なのですが、この場合直前に$iに0を代入して、変数化してあげれば先ほどと同じ書き方で出力可能です。

<?php
$i = 0;
echo $xml->channel->item->0->title
; ?>

以上でRSSの基本的な出力方法についてはおしまいです。