PHPで天気予報を求める(その2)

(1/1)
PHP で天気予報を求める」では、livedoor の WeatherHacks を用いて天気予報を表示している。ところが、この API では今日を含めて 3 日間の天気予報しか表示しない。一方、livedoor 天気情報 では、RSS 形式で 1週間分の各地の予報を配信している。
そこで今回は、この RSS を取得し、任意の都市の週間天気予報を表示するプログラムを作ってみることにする。

「livedoor天気情報」の天気予報情報

livedoor 天気情報は、RSS 2.0 形式で天気予報情報を配信している。
各地点の RSS の URL は「全国の地点定義表(RSS)」に示されている URL である。

サンプル・プログラム

プログラムを実行する

ダウンロード(PHP4/5共用)

サンプル・プログラムの解説:天気予報情報の取り出し

入力処理については、「PHP で天気予報を求める」とほぼ同じである。
space
WebAPI の代わりに、RSS から情報を取り出すユーザー関数 getWeeklyWeather を用意した。
RSS 2.0 の仕様にしたがって、情報を配列変数に格納している。
space

0215: /**
0216:  * 週間天気予報情報を取得する
0217:  * @param string $rss   livedoor天気情報RSSを示すURL
0218:  * @param array  $items 週間天気予報情報を格納する配列
0219:  * @return int 配列に格納した情報件数/0=失敗
0220: */
0221: function getWeeklyWeather($rss, &$items) {
0222:     //PHP4用; DOM XML利用
0223:     if (isphp5() == FALSE) {
0224:         $dom = read_xml($rss);
0225:         $cnt = 0;
0226:         if ($dom != FALSE) {
0227:             //DOMから必要な情報を配列へ
0228:             $node_rss  = $dom->get_elements_by_tagname('rss');
0229:             $node_item = $node_rss[0]->get_elements_by_tagname('item');
0230:             foreach ($node_item as $item) {
0231:                 $node = $item->get_elements_by_tagname('title');
0232:                 $title = $node[0]->get_content();
0233:                 if (getMonthDay($title) != FALSE) {
0234:                     list($items[$cnt]['city'], $items[$cnt]['month'],
0235:                         $items[$cnt]['day'], $items[$cnt]['week'])
0236:                         = getMonthDay($title);
0237:                     $node_image = $item->get_elements_by_tagname('image');
0238:                     $node = $node_image[0]->get_elements_by_tagname('title');
0239:                     $items[$cnt]['weather'] = $node[0]->get_content();
0240:                     $node = $node_image[0]->get_elements_by_tagname('url');
0241:                     $items[$cnt]['image'] = $node[0]->get_content();
0242:                     $node = $item->get_elements_by_tagname('description');
0243:                     $description = $node[0]->get_content();
0244:                     if (getTemperature($description) != FALSE) {
0245:                         list($items[$cnt]['temp_max'], $items[$cnt]['temp_min']) = getTemperature($description);
0246:                     } else {
0247:                         $items[$cnt]['temp_max'] = '-';
0248:                         $items[$cnt]['temp_min'] = '-';
0249:                     }
0250:                     $cnt++;
0251:                 }
0252:             }
0253:         }
0254:     //PHP5用; SimpleXML利用
0255:     } else {
0256:         $node_rss = simplexml_load_file($rss);
0257:         //レスポンス・チェック
0258:         if (isset($node_rss->channel) == FALSE)  return FALSE;
0259:         //必要な情報を配列へ
0260:         $cnt = 0;
0261:         foreach ($node_rss->channel->item as $item) {
0262:             $title = (string)$item->title;
0263:             if (getMonthDay($title) != FALSE) {
0264:                 list($items[$cnt]['city'], $items[$cnt]['month'],
0265:                     $items[$cnt]['day'], $items[$cnt]['week'])
0266:                         = getMonthDay($title);
0267:                 $items[$cnt]['weather'] = (string)$item->image->title;
0268:                 $items[$cnt]['image']   = (string)$item->image->url;
0269:                 $description = (string)$item->description;
0270:                 if (getTemperature($description) != FALSE) {
0271:                     list($items[$cnt]['temp_max'], $items[$cnt]['temp_min']) = getTemperature($description);
0272:                 } else {
0273:                     $items[$cnt]['temp_max'] = '-';
0274:                     $items[$cnt]['temp_min'] = '-';
0275:                 }
0276:                 $cnt++;
0277:             }
0278:         }
0279:     }
0280:     return $cnt;
0281: }

サンプル・プログラムの解説:出力処理

今回は、画面に出力するコンテンツを $html_header, $html_outstr, $html_footer の 3 つに分割し、必要に応じて表示するようにした。週間予報の table が含まれているのは $html_outstr である。
space
なぜ、このようなロジックにしたかというと、コマンドラインで
WeeklyWeather.php?id=63
のように ID を指定することで、ある地点の天気予報 table のみを表示させたかったからである。つまり、このスクリプトをホームページやブログの一部として組み込むことで、今日から 1週間分の天気予報を表示するガジェットになる。
space
また、親となるホームページやブログの文字コードセットにあわせ、charset 変数で出力文字コードを変更できるようにした。たとえば
WeeklyWeather.php?id=6&charset=SJIS
とすると、東京の週間天気予報をシフト JIS で出力することができる。

0473: //ID指定の場合は結果のみ出力
0474: if ($id == '') {
0475:     echo $html_header;
0476:     echo $html_outstr;
0477:     echo $html_footer;
0478: else {
0479:     echo mb_convert_encoding($html_outstr$EncodeOutput$EncodeInternal);
0480: }

参考書籍

参考サイト

(この項おわり)
header