PHPプロ!TIPS+

1. 天気情報を取得できるAPIを使ってみよう

PHPなどのWebアプリケーションを作成するときに、API(アプリケーション・プログラミング・インタフェース、Application Programming Interface)サービスを利用して、Webサイトを作成する機会が多くなっているのではないでしょうか?

今回は実際に天気APIサービスを利用して、天気情報を出力してみましょう。

APIの出力データ形式には、比較的XMLを使用することが多いです。

今回は、PHP4でXMLを使用するためのライブラリPEAR::XML_SerializerとPHP5から使用できるようになったSimple_XMLを使用して、天気情報を出力します。

天気情報APIとして、Livedoor社提供の「weather hacks」というAPIを使用します。
http://weather.livedoor.com/weather_hacks/

PEAR::XML_Serializerのインストール方法は下記のTipsをご参照ください。
http://www.phppro.jp/phptips/archives/vol28/

ここでは、PEAR::XML_Serializerで今日の東京の天気をSimple_XMLで明日の東京の天気を取得しています。

それでは、実際に以下のスクリプトを実行してみましょう。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>お天気API</title>
</head>
<body>
<?php
//PEAR::XML_Serializerでの実装方法
require_once("XML/Unserializer.php");
$base_url 
"http://weather.livedoor.com/forecast/webservice/rest/v1?city=63&day=today";
$xmldoc join("",file($base_url));
$opt array (
'complexType' => 'object',
'parseAttributes' => 'true',
'attribuesArray' => '_attributes',
);
$xml = new XML_Unserializer($opt);
$xml -> unserialize($xmldocfalse);
$xml $xml->getUnserializedData();
$place $xml->location->pref $xml->location->city;
$img $xml->image->url;
$img_width $xml->image->width;
$img_height $xml->image->height;
$url $xml->link;
$description nl2br($xml->description);
$date_rfc822 $xml->forecastdate;
$date date("m/j(D)",strtotime($date_rfc822));
$telop $xml->telop;
print <<< DOC_END
<div>
<div>
{$place}({$date})
<a href=
$url target="_blank">
<img src=
$img border="0" alt=$place hegiht="$img_height" width="$img_width">
</a>
{$telop}<br>
{$description}
<br />
</div>
</div>
DOC_END;
?>
<hr />
<?php
//Simple_XMLでの実装方法
$base_url 
"http://weather.livedoor.com/forecast/webservice/rest/v1?city=63&day=tomorrow";
$xml simplexml_load_file($base_url);
$city_name $xml->location->attributes();
$place $city_name["pref"] . $city_name["city"];
$img $xml->image->url;
$img_width $xml->image->width;
$img_height $xml->image->height;
$url $xml->link;
$description nl2br($xml->description);
$date_rfc822 $xml->forecastdate;
$date date("m/j(D)",strtotime($date_rfc822));
$telop $xml->telop;
print <<< DOC_END
<div>
<div>
{$place}({$date})
<a href=
$url target="_blank">
<img src=
$img border="0" alt=$place hegiht="$img_height" width="$img_width">
</a>
{$telop}<br>
{$description}
<br />
</div>
</div>
DOC_END;
?>
</body>
</html>

このように、weather hacksのAPIを使用することで簡単に天気情報を出力できました。 取得できる情報などをもっと詳しく知りたい方は以下のURLをご参照ください。
http://weather.livedoor.com/weather_hacks/webservice.html

非公式のパッケージですが、PEARのライブラリとしても使用することができます。
pear install http://p4life.jp/services_livedoor/Services_Livedoor-0.1.0.tgz

他にも天気情報を提供しているところがあります。
http://www.weathermap.co.jp/hitokuchi_rss/
http://developer.yahoo.com/weather/index.html

海外のyahooが天気APIを一般公開していますが、詳細な日本のデータとしては紹介したサイトに比べると、まだまだ使用できる段階ではありません。

また、紹介したサイトの天気情報は個人利用では無料で使用できますが、商用利用としては許可されていないものもありますので、気をつけて使用しましょう。

今日、地図のAPIや天気情報のAPIなど、いろいろなAPIが公開されています。この機会に是非、皆さんも天気情報以外のXMLで記述されたAPIをPHPで取得し、使用してみてはいかがでしょうか。

2. ob_get_contentsを使用した簡単テンプレート

ob_get_contents()関数を利用したお手軽なテンプレートについて紹介したいと思います。

おそらく大抵のPHPのアプリケーションであれば、Smartyなど何らかのテンプレートエンジンを使用していると思います。今回はHTMLの出力ではなく、もっと簡単にPHP内蔵の機能を使用してテンプレートを作る方法を紹介したいと思います。

今回はメールの文面について考えてみましょう。Smartyを使用している場合は、fetch()メソッドを使用してテンプレートから変数を割り当てたメールの文面を作成するでしょう。ただ、SmartyをHTML用に立ち上げている場合に文字コードの変換であったり、コンパイルディレクトリやキャッシュ用のディレクトリを共有して問題になることもあるかもしれません。

今回はPHP内蔵の出力制御関数を使用してPHPファイルをテンプレートとして扱います。まずは以下のスクリプトを見てください。

<?php

$list 
array(
  
"key1" => "val1",
  
"key2" => "val2",
  
"key3" => "val3",
);

ob_start();
include(
"/path/to/template.php");
$body ob_get_contents();
ob_end_clean();

このスクリプトで使用するtemplate.phpを以下のように作成します。

<?php foreach($list as $key => $val): ?>
<?php 
echo $key ?>の値は<?php echo $val ?>

<?php endforeach; ?>

template.phpを保存して先ほどのスクリプトを実行すると、$bodyに以下の文字列が代入されます。

key1の値はval1
key2の値はval2
key3の値はval3

テンプレートエンジンに慣れているとtemplate.phpが若干読みづらいかもしれません。ただ、ちょっとしたテンプレートで、外部に保存しておきたいときなどは、Smartyの仕組みを使用してとやるよりもお手軽でしょう。

では、先ほどのスクリプトを見てみましょう。といっても内部で実行しているのは非常に簡単なもので、以下の3つを実行しているだけです。

  • ob_start()関数でPHPの出力バッファを有効にする。
  • template.phpをインクルード
  • インクルードしたときの出力をob_get_contents()関数で$body変数に保存
  • 出力バッファにためられた内容をクリア

PHPには、出力された内容をすぐにブラウザに送信するのではなくバッファにためておく仕組みがあります。この仕組みを今回は使用しているわけです。

元からあるPHPの機能を使用するので、特に設定を行う必要もありません。複雑なテンプレートを構成する場合はやはり可読性の面からSmartyの方がよいですが、簡単なものであればこのようにささっと実装してしまうのも1つの手ではないでしょうか。

バックナンバーについて

TIPS-MLは、毎週金曜日に更新され、新しい記事が掲載されます。

Tipsꗗy[W 

Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)