レベル: 中級 Brian M. Carey, Information Systems Consultant, Triangle Information Solutions
2009年 7月 28日 Atom は、Web サイトに掲載された情報を特定するための XML 仕様です。Web 開発者が Atom を使用してフィードを生成すれば、他の Web 開発者 (またはフィード・リーダーを使用するユーザー) がそのフィードによって簡単に、リモート・サイトに掲載されている興味深い情報を見つけて表示することができます。Atom はいわば Web サイトの索引といったようなもので、必要とする誰もが使用することができます。そして、ほとんどのホスト・プロバイダーがサポートしている人気の言語、PHP を使用することで、Web 開発者は各種のフィード・リーダーや他の Web 開発者たちが利用できる Atom フィードを簡単に作成することができます。その究極の結果は、Web コンテンツをさらに幅広い読者に広めることができる最先端の情報ソリューションです。
Atom とは何か
 |
よく使われる頭字語
- HTML: Hypertext Markup Language
- RSS: Really Simple Syndication
- SQL: Structured Query Language
- URL: Uniform Resource Locator
- XHTML: Extensible Hypertext Markup Language
- XML: Extensible Markup Language
|
|
この記事でも使われているように、Atom は Web パブリッシャーがその Web サイトのコンテンツをさまざまなコンシューマーに配信できるようにする XML 言語です。パブリッシャーは Atom を使用することで、Web フィードを標準化されたフォーマットで作成することができます。標準フォーマットのフィードでは、ユーザーがフィード・リーダーとして知られるソフトウェアを使って Web サイトのコンテンツを読むことができます。また、他の Web 開発者たちがそれぞれの Web サイトでフィードのコンテンツをパブリッシュすることも可能です。
配信のための標準として現在使用されているのは、もちろん Atom だけではありません。RSS も同じく標準化されたフォーマット (同じく XML を使用) であり、Atom よりも前から存在しています。実のところ、Atom は RSS に伴う特定の制約に対処するために作成されたものです。
したがって、Atom 仕様には RSS に勝る多くの利点があります。Atom には、提供するデータのフォーマット (HTML、XHTML など) を定義する手段がありますが、RSS にはありません。また、Atom は RSS とは異なり、xml:lang 属性によって国際化対応をサポートします。さらに Atom で使用する日付フォーマットは、RSS が従う RFC (Request for Comments) 822 ではなく RFC 3339 に従っているため、最先端の (そして標準化された) 日付フォーマットを使用することができます。
Atom で PHP を使用する理由とは?
PHP は、PHP: Hypertext Processor の略です。スペルアウトしても元の頭字語が含まれる頭字語は、英語ではおそらく PHP 以外にはないでしょう。歴史的に見ると、この PHP という語は当初 Personal Home Page を表していました。
PHP は、動的なサーバー・サイドのコンテンツを生成するスクリプト言語です。HTML との相性が良いことから、動的コンテンツを支援するために PHP コードが標準 HTML Web ページに組み込まれることは珍しくありません。
PHP は、データベース管理システムである MySQL との相性も抜群です。Web 開発の歴史において、この 2 つの技術は共に進化を果たし、数えきれないほどの場面で連携してきました。その理由はほぼ間違いなく、1 つの否定できない重要な事実に基づいています。それは、どちらも無料であることです。
このセクションの冒頭に挙げた質問 (Atom で PHP を使用する理由とは?) に答えると、開発者は PHP を使うことで、読みやすく、開発しやすい方法で動的なコンテンツを柔軟に生成できるからです。動的コンテンツは MySQL データベースから取得します。そして PHP を使って出力ページ (フィード) をコーディングすれば、Atom 仕様に準拠した XML 出力がレンダリングされます。
この記事での説明は、読者が MySQL と PHP の基礎を十分に理解していることを前提にしています。この前提に当てはまらない場合は、記事の「参考文献」セクションに記載されている初心者用のチュートリアルへのリンクを参照してください。
ビジネスでの使用ケースの定義: 釣りレポート
あなたのオフィスに上司が入ってきました。彼は自社の Web サイト (fishinhole.com) の運営方法を大変気に入っています。このサイトでは現在、あらゆる種類の釣り道具を釣り愛好家に宣伝、販売しています。このサイトには釣りレポートのフォーラムもあり、サイトを訪れた釣り愛好家たちが自分の自慢話を互いに披露する場になっています。
上司は (断りもなく) あなたのオフィスの椅子に腰をおろし、Web サイトが十分に広まっていないと文句を言い始めました。彼は、Web ページの釣りレポートのセクションを「エサ」に、もっと多くの釣り愛好家をこの Web サイトに「釣りたい」と考えています。そこで彼はあなたに、Web サイトのこのセクションを、世界中の釣りレポートを集めた「ワンストップ・ショップ」にするように指示しました。この指示に従うことは、(上司が言うには) fishinhole.com の成功を維持するには不可欠です。それだけ言うと上司はコーヒーをすすってにっこりと笑い、オフィスを出ていきました。
あなたは椅子にもたれかかり、釣りレポート・フォーラムを広める手段は一体何だとうと考え始めるや否や、すぐに名案が浮かんできました。配信です! fishinhole.com のユーザーや商品購入者がレポート・セクションを見られるようにするだけでなく、フォーラムを配信すれば、人々がフィード・リーダーを使って釣りレポートの概要を読むことができます。さらに、他の Web 開発者の Web ページにその配信フィードが組み込まれる可能性もあります。いずれにしても、ユーザーが興味を持ったレポートのタイトルをクリックすれば fishinhole.com にリンクされるため、釣り道具のダイレクト・マーケティングを次々とユーザーに公開することができます。これはまさに名案です。
データベース設計
釣りレポート・フォーラムのデータベースは、上司があなたのオフィスに入ってくるよりも前に、とっくに設計済みです。Web ページにはすでに釣りレポートのセクションがあることを思い出してください。このセクションは、単に配信されていなかったというだけにすぎません。
コンテンツを配信するために必要なデータベースの変更は何かと言えば、実は何もありません!これが、配信の素晴らしい点の 1 つです。ほとんどの場合、既存のスキーマやデータ・モデルを変更しなくても記事を配信することができますが、その理由は配信する記事には必ずと言っていいほど、Atom 仕様が要件とする情報が備わっているからです。
リスト 1 は、fishinhole.com の釣りレポート・セクションで現在使用しているデータベース・モデルです。ここには INSERT 文も用意されているので、テスト用のデータをデータベースに含めることができます。
リスト 1.REPORTS テーブルの構造と INSERT文
CREATE TABLE IF NOT EXISTS `reports` (
`ID` bigint(20) NOT NULL auto_increment,
`AUTHOR` varchar(32) NOT NULL,
`TITLE` varchar(64) NOT NULL,
`SUBTITLE` varchar(128) NOT NULL,
`CONTENT` varchar(2000) NOT NULL,
`POSTED` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
INSERT INTO `reports` (`id`, `author`, `title`, `subtitle`, `content`, `posted`) VALUES
(1, 'BigRed', 'Spanish Bite Looking Good!', 'Near the Cape!',
'Trolled for 3 hours and limited out on Spanish Macks! Watch out for the shallows
near green can #4.', '2009-05-03 04:54:33'),
(2, 'JonBoy', 'Big Rock Report', 'Spring has sprung',
'Caught several blackfins and mahi just outside of the Big Rock on Saturday.
We were using flourescent squid teasers with ballyhoo for hookups.
One Mahi weighed over 50#!', '2009-05-03 04:56:06'),
(3, 'Erasmus', 'Drum in the backwaters', 'The bite was hot!',
'Loaded up against the marsh grass, boys. Go get em. I was using gulp
with 1/4 ounce jigheads.', '2009-05-03 04:57:19'),
(4, 'ReelHooked', 'Speckled Trout In Old River', 'Limited out by noon',
'They were schooling heavy in Old River. They would eat anything we would
throw at them. Most were undersized, but we managed to keep some
and had our fill by midday.', '2009-05-03 04:59:00');
|
この記事に記載するコードを実際にテストするには、fishinhole という MySQL データベースを作成して、そのデータベースでリスト 1 のコードを実行します。
最初の列 (ID) はテーブルの主キーです。この ID 列は auto_increment 仕様を使用しているため、新しい行がテーブルに挿入されるたびに、その新しい行の ID 列には前の行の ID 列の値をインクリメントした値が設定されます。これは Oracle のテーブルでのシーケンスと同様です。
AUTHOR 列は、釣りレポートの投稿者のユーザー名を指定します。この名前はユーザーの本名ではなく、ユーザーのスクリーン・ネームです (もちろん、ユーザーの本名そのものがスクリーン・ネームとして使われる場合もあります)。
TITLE 列は単なる記事のタイトルです。同様に、SUBTITLE は記事のサブタイトルで、Atom フィードではサブタイトルを記事の概要として使用します。
CONTENT 列は、実際の釣りレポートそのものです。ここで生成される Atom フィードには記事全体の概要だけが記載されるため (ユーザーがリンクをクリックして Web サイトにアクセスしたくなるようにするためです)、コンテンツ自体は Atom フィードに表示されません。
最後の POSTED 列は、記事が Web サイトに投稿された日付が格納される DATETIME 列です。
複雑にならないように、ここでは少数 (4 つ) の記事しか提供していませんが、実際には何百人もの著者から何千もの記事が投稿されることになります。
作業の開始
データベースの設計は用意できているので、これから早速、Atom フィードを生成するように PHP ページのコーディングを行います。この記事では、PHP を使ってテストできる単純な Atom フィードを作成するための基本手順を説明します。
コードをテストするには、PHP プロセッサーにアクセスする必要があることに注意してください。大抵のホスティング・ソリューションでは、PHP プロセッサーにアクセスすることができます。また、ローカルで PHP プロセッサーにアクセスする場合もあります。お使いの Web 環境で PHP 文書を実行する方法については、システム管理者または技術サポート・スタッフに問い合わせてください。
PHP でデータベースにアクセスする
syndication.php という名前の PHP ファイルを新規に作成してください。これからこのファイルに、コードを配置していきます。
前述したように、PHP と MySQL には、極めて相性良く連動してきた数々の歴史があります。この 2 つは極めて深く関係していると言う人もいるでしょうが、そのような判断はこの記事の範囲外です。
リスト 2 に、リスト 1 のコードで作成した MySQL データベースにアクセスするための基本的なコード・スニペットを記載します。
リスト 2. PHP での MySQL データベースへのアクセス
$link = mysql_connect('localhost', 'admin', 'password')
or die('Could not connect: ' . mysql_error());
mysql_select_db('fishinhole') or die('Could not select database');
$query = 'SELECT id,title,subtitle,author,posted
FROM reports order by posted desc limit 25';
;
$result = mysql_query($query)
or die('Query failed: ' . mysql_error());
|
実のところ、上記のコードはかなりの部分をカバーしているので、順を追ってその内容を説明します。
このコードはまず、mysql_connect() 関数から始まります。パラメーターは、お使いの環境の仕様に応じて変更する必要があります。最初のパラメーターは、データベース・ホストです。データベース・ホストはリスト 2 とまったく同じこともあれば (つまり、localhost)、リモート・ホスト (例えば、IP アドレス 10.92.2.1 など) になることもあります。また、DNS (Domain Name System) による変換を行っている場合には実際のホスト名 (mysql.myhost.com など) になる場合もあります。
2 番目のパラメーターは、このデータベースにアクセスする MySQL ユーザーの名前です。上記の admin を使用できるのは、MySQL 環境内でこれ以外に有効なアカウントがない場合だけです。MySQL データベースのアカウントを作成する方法については、MySQL のドキュメントを参照してください。注意する点として、ここで使用するアカウントには、REPORTS データベースに対する読み取りアクセス権が必要です。
3 番目のパラメーターはユーザーのパスワードです。このパスワードは、2 番目のパラメーターで識別されるユーザーに対して使用するパスワードと同じでなければなりません。
or die 節は、障害が発生した場合に、診断情報を提供するために組み込まれています。これにより、データベース管理システムとの接続が確立できない場合には、PHP スクリプトの実行時に接続が失敗したこと、そしてその理由を示すメッセージを受け取ることになります。
次に続く mysql_select_db() 関数では、使用するデータベースを実際に選択します。開発者それぞれがインストールしている MySQL には多くのデータベースを含めることができます (そうする傾向が大です)。そのため、どのデータベースを使用するかを指定することが重要となります。
記事に付属のコードの機能をテストするには、fishinhole という名前の MySQL データベースを作成するように推奨したことを思い出してください。mysql_select_db() の行では、このデータベースの使用を指定しています。
続いて実際のクエリーがあります。この例では、クエリーを単にストリングで定義し、REPORTS テーブルから ID、TITLE、SUBTITLE、AUTHOR、および POSTED 列を取得しています。order by posted desc 節によって、クエリーは POSTED 列のデータ (記事が Web サイトに投稿された日付) を基準に降順で行を返すように指定されます。そのため、最新の記事から順に取得することになります。これは、フィードでは標準的なプラクティスです。
最後の limit 25 は重要な節です。この節で、このフィードに返す記事の数を最大 25 に指定しています。前にも言ったように、このようなフォーラムには何千もの記事があるものですが、フィードに何千もの記事を返すとなると現実的ではありません。莫大な帯域幅が使用され、ほとんどのフィード・コンシューマーが長い間待たされることになるからです。
このクエリーはストリングとして、$query という直観的な名前の変数に割り当てられます。
mysql_query() 関数では、前の行に定義されたクエリーを実際に実行します。クエリーの結果は、 $result 変数に格納されます。ここでも同じく、診断のために or die 節が組み込まれています。
ループと Atom 仕様
データベースからデータを取得できるようになったところで、今度はそのデータを Atom 仕様に準拠したフォーマットで表示する作業に取り掛かります。Atom は XML 言語です。そのため、PHP ファイルは HTML フォーマットではなく、XML フォーマットで出力されます。Web ブラウザーで出力を表示するつもりなら、ブラウザーとバージョンによって表示が異なることを念頭に置いておいてください。通常、XML 出力を表示するのに最も簡単な方法は、ブラウザーで出力を右クリックし、View Source (ソースの表示) を選択することです。すると、処理されていない状態の XML 出力が表示されます。
各記事に関する情報を表示する前に、Atom フィードにプリアンブルを組み込んでおく必要があります。プリアンブルとは出力を Atom フィードとして識別するセクションのことで、ここに、フィードについての関連情報を含めることになります (リスト 3 を参照)。
リスト 3. Atom のプリアンブル
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
<title>Fishing Reports</title>
<subtitle>The latest reports from fishinhole.com</subtitle>
<link href="http://www.fishinhole.com/reports/syndication.php" rel="self"/>
<updated><?php echo date3339(); ?></updated>
<author>
<name>NameOfYourBoss</name>
<email>nameofyourboss@fishinhole.com</email>
</author>
<id>
tag:fishinhole.com,2008:http://www.fishinhole.com/reports/syndication.php
</id>
|
一目見てわかるように、リスト 3 のコードは PHP のようには見えません。それもそのはずで、コードの大部分は PHP ではなく、動的コンテンツをほとんど使わない標準化された出力だからです。
この XML 文書を Atom フィードとして識別するのは <feed> 要素です。要素を定義するために使用する名前空間は、<feed> 要素の属性として指定します。また、前述の xml:lang 属性を使用して、これが英語で書かれた文書であることを指定します。
<title> 要素は、フィード全体のタイトルを指定します。同様に、<subtitle> 要素はフィード全体のサブタイトルを指定します。
<link> 要素が指定するのは、この syndication.php 文書の URL です。この例でのアドレスは、この記事で説明する架空の世界では有効ですが、現実の世界では機能しません。実際には、このフィードの出力を生成するリンクをここに組み込めます。
<updated> 要素は、このフィードのコンシューマーに最終更新日時を知らせるタイムスタンプ (RFC 3339 標準に準拠) を生成します。この例ではデータベースから最新のデータを取得することから、フィードは常に最新の状態になるので、現在のタイムスタンプを使用します。また、この要素にはわずかですが PHP コードのスニペットが含まれていることに注意してください。これが、タイムスタンプを RFC 3339 フォーマットで生成する、カスタムで作成した PHP 関数です。
<author> 要素は、フィード全体の作成者を定義します。このフィードは上司の考えなので、ここには作成者として上司の名前を使うことになります。
そして最後の <id> 要素は、このフィードを IRI (Internationalized Resource Identifier) フォーマットで一意に識別します。
リスト 4 は、Atom フィードの各エントリーを生成するメイン・ループです。フィードを生成する作業の大部分は、このループで行われます。
リスト 4. ループ
<?php
$i = 0;
while($row = mysql_fetch_array($result))
{
if ($i > 0) {
echo "</entry>";
}
$articleDate = $row['posted'];
$articleDateRfc3339 = date3339(strtotime($articleDate));
echo "<entry>";
echo "<title>";
echo $row['title'];
echo "</title>";
echo "<link type='text/html'
href='http://www.fishinhole.com/reports/report.php?
id=".$row['id']."'/>";
echo "<id>";
echo "tag:fishinhole.com,2008:http:
//www.fishinhole.com/reports/report.php?id=".$row['id'];
echo "</id>";
echo "<updated>";
echo $articleDateRfc3339;
echo "</updated>";
echo "<author>";
echo "<name>";
echo $row['author'];
echo "</name>";
echo "</author>";
echo "<summary>";
echo $row['subtitle'];
echo "</summary>";
$i++;
}
?>
|
繰り返しますが、リスト 4 の内容はフィードを生成する作業のかなりの部分に及びます。最初にあるのは while ループです。基本的にコードのこの部分が行っている処理は、「テーブルのなかに出力にまだ含まれていない行がある限り、処理を続けること」です。各繰り返し処理での現在の行は、$row という直観的な名前のPHP 変数に格納されます。
次に、カウンター ($i) がチェックされます。カウンターの値が 0 よりも大きければ、これが 2 番目以降の繰り返し処理であることを意味します。その場合には、前の繰り返し処理での <entry> 要素を閉じる必要があります。
これに続く 2 行では、記事の日付を (POSTED 列から) 取得し、その日付を前述の PHP 関数を使って RFC 3339 フォーマットに変換します。
続いて <entry> 要素が始まります。その後の <title> 要素には、現在の行の TITLE 列からの値が入力されます。
<link> 要素は、子テキストが含まれていないという点で独特です。子テキストの代わりに、実際のリンクが属性として参照されます。これは Atom 標準の一部です。このリンクは、記事全文を読むことのできる URL をユーザーに示しているにすぎません。前にも説明したように、このフィードはユーザーに概要だけを提供します。
<id> 要素は前に説明した <id> 要素と同じように、このエントリーを IRI フォーマットで一意に識別します。そして前と同じく、この要素も関連 URL から作成されます。
<updated> 要素には、POSTED 列の DATETIME 値 (RFC 3339 フォーマット) が含まれます。この文書の $articleDateRfc3339 変数は、この繰り返し処理で入力済みであることを思い出してください。
次に続くのは <author> 要素です。この要素は他の要素と違って (ただしプリアンブルの <author> 要素と同じく)、複数の子要素があります。これらの子要素のうち、この記事で使用しているのは作成者の名前だけです。作成者の名前は、現在の行の AUTHOR 列から入力されます。
<summary> 要素には、現在の行の SUBTITLE 列から集められた情報が含まれます。
最後にループ・カウンター ($i) がインクリメントされ、ループが続行します。
要するにこれが、REPORTS テーブルから Atom 文書を生成するために必要なすべてのコードです。ご覧のように、最初に思ったほど複雑ではないはずです。
もう 1 つ注意する点として、Atom 仕様の要素の多くは、ここでは取り上げられていません。しかしコードのこのセクションで説明したパターンに従えば、他の要素も簡単に追加することができます。詳細については、「参考文献」を参照してください。
テストしてみましょう!
ここからが面白い部分です。いよいよ、このコードをテストしてみます。
上記のコード・リストに記載したすべての内容を再入力 (またはコピー・アンド・ペースト) する代わりに、「ダウンロード」セクションに用意されている PHP ファイルをそのまま使用することができます。このファイルをローカル・ディレクトリーにコピーして、前に説明したデータベースに必要な変更 (ユーザー名、パスワード、ホストの変更) を加えてください。それが済んだら、データベースにアクセス可能な PHP ファイル構造にファイルをコピーします。
PHP ファイルを正しい場所に配置したら、ブラウザーを立ち上げて、http://<皆さんの環境でのホスト名>/<皆さんの環境でのコンテキスト>/syndication.php を指定してファイルにアクセスします。
カスタマイズされたソリューションの常として、<XXXX> で表されているところは、皆さんの環境に合わせて指定する必要があります。
前にも言いましたが、表示される結果は、使用しているブラウザーとバージョンによって異なります。最近のブラウザーには、これが Atom フィードであると検出して、それに応じて結果を表示するものもあれば、そのままの XML フォーマットで表示するものもあります。さらに、この文書は標準の HTML 文書でないことから、何も表示しないブラウザーもあります。
ブラウザーが未加工の XML を表示しない場合は、文書を右クリックし、View Source (ソースの表示) を選択することで XML を表示することができます。すると、リスト 5 のような出力が表示されるはずです。
リスト 5. 出力 (省略版)
<?xml version='1.0' encoding='iso-8859-1' ?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
<title>Fishing Reports</title>
<subtitle>The latest reports from fishinhole.com</subtitle>
<link href="http://www.fishinhole.com/reports" rel="self"/>
<updated>2009-05-03T16:19:54-05:00</updated>
<author>
<name>NameOfYourBoss</name>
<email>nameofyourboss@fishinhole.com</email>
</author>
<id>tag:fishinhole.com,2008:http://www.fishinhole.com/reports</id>
<entry>
<title>Speckled Trout In Old River</title>
<link type='text/html' href='http://www.fishinhole.com/reports/report.php?id=4'/>
<id>tag:fishinhole.com,2008:http://www.fishinhole.com/reports/report.php?id=4</id>
<updated>2009-05-03T04:59:00-05:00</updated>
<author>
<name>ReelHooked</name>
</author>
<summary>Limited out by noon</summary>
</entry>
...
</feed>
|
もう 1 つのテスト方法は、フィードが有効であることを確認することです。それには、サイバースペースで見つかる数多くの Atom フィード・バリデーターのいずれかを使用することができます。なかでも優れているのは、http://www.feedvalidator.org です。この Web サイトでは、Atom、RSS、および KML (Keyhole Markup Language) フォーマットのフィードを検証します。
業績
Atom フィードを実装してデプロイしたおかげで、世界中の何千人もの新しい釣り愛好家が Web サイトの釣りレポートにアクセスしてくるようになりました。さらに、作成した Atom フィードを組み込んでいる釣りのサイトから何百ものリンクが張られています。釣り愛好家のなかには、フィード・リーダーを使って毎日のようにこの釣りレポートを見ている人もいるほどです。
最新のトラフィック・レポートを見た上司が、あなたのオフィスにやってきました。彼はアクセス件数が増えたことにご満悦で、Web サイトへのユニーク・ビジター数が 10% も増加したと報告してきました。上司は親指を立て、コーヒーをすすりながらオフィスから出ていきました。
まとめ
Atom 仕様は Web コンテンツを配信するには理想的な手段です。PHP と MySQL を併せて使うことによって、Atom 標準に適合した Web フィードを簡単に生成することができます。しかも、このフィードはデータベースから直接読み取るため、常に最新の状態です。このフィードはフィード・リーダーで読み取ることも、他の Web サイトに組み込むこともできます。その結果、Web コンテンツはより広く公開されることになります。つまり、アクセス件数が増えるということで、それによって収益も上がるはずです。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| The PHP file used in this article | syndication.php | 3KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
- IBM 製品の評価版: DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を体験するには、IBM SOA Sandbox のオンライン試用版をダウンロードするか、検討してみてください。
議論するために
著者について  | 
|  | Brian Carey は、Java エンタープライズ・アプリケーションのアーキテクチャー、設計、実装を専門とする情報システムのコンサルタントです。Brian は Twitter でつぶやきを公開しているので、彼をフォローすることができます (http://twitter.com/brianmcarey)。 |
記事の評価
|