PHPのDOMでRSS作成

ブログ等では記事を書くと勝手にRSS生成されるが、自前HPなどでRSS対応したい場合、自力で作る必要がある。
例えば、Osada’s Software!では、シェアウェアであるRSSエディタ Headline-Editorを使用しRSSを作成している。作成していた。

これはこれで大変便利で重宝している。
しかし、動的にページ更新されるようなサイトには不向き。

そんな訳で、RSSを作成するためのPHPプログラムを作ってみた。
仕様は以下の通り。
# 更に細かな仕様はソース参照。
PHPバージョン:PHP4、PHP5
RSSバージョン:RSS2.0
文字コード:UTF-8

<?php
rssWrite(“タイトル”,”説明”);
/******************/
/* RSS2.0保存処理 */
/******************/
function rssWrite($item_title,  // 追加アイテムのタイトル名
         $item_description)     // 追加アイテムの説明
{
  // RSS出力ファイル名
  $rss_file = “index.xml”;
  // サイト名
  $site_name = “RSSテスト用サイト”;
  // サイト説明
  $site_description = “RSS2.0保存テスト用のサイト”;
  // サイトURL
  $url = “http://”.$_SERVER["HTTP_HOST"].$reqdir.”/”;
  if(substr(PHP_VERSION, 0, 1) >= 5){
    /******************/
    /* PHP5以降の場合 */
    /******************/
    // RSSファイルが存在するか確認
    if(file_exists($rss_file)){
      // 存在する場合は読み込む
      $dom = new DOMDocument(“1.0″, “utf-8″);
      $dom->load($rss_file);
      // <channel>ノード
      $channelNodeList = $dom->getElementsByTagName(“channel”);
      $channelNode = $channelNodeList->item(0);
    }else{
      // 存在しない場合は新たに作成する
      $dom = new DOMDocument(“1.0″, “utf-8″);
      // <rss>ルートノード
      $rssNode = $dom->createElement(“rss”);
      $rssNode->setAttribute(“version”,”2.0″);
      $dom->appendChild($rssNode);
      // <channel>を作成し、<rss>に追加
      $channelNode = $dom->createElement(“channel”);
      $rssNode->appendChild($channelNode);
      // <title>を作成し、<channel>に追加
      $titleNode = $dom->createElement(
                   “title”,
                   mb_convert_encoding($site_name,”UTF-8″, “auto”));
      $channelNode->appendChild( $titleNode );
      // <link>を作成し、<channel>に追加
      $linkNode = $dom->createElement(“link”,$url);
      $channelNode->appendChild( $linkNode );
      // <description>を作成し、<channel>に追加
      $descriptionNode = $dom->createElement(
                         “description”,
                         $site_description);
      $channelNode->appendChild( $descriptionNode );
      // <lastBuildDate>を作成し、<channel>に追加
      // <lastBuildDate>には、現在日時を格納する
      $lastBuildDateNode = $dom->createElement(
                           “lastBuildDate”,
                           date(“D, d M Y H:i:s +0900″));
      $channelNode->appendChild( $lastBuildDateNode );
      // <language>を作成し、<channel>に追加
      $languageNode = $dom->createElement(“language”,”ja”);
      $channelNode->appendChild( $languageNode );
    }
    // <item>を作成し、<channel>に追加
    $itemNode = $dom->createElement(“item”);
    $channelNode->appendChild($itemNode);
    // <title>を作成し、<item>に追加
    $titleItemNode = $dom->createElement(
                     “title”,
                     $site_name.” – “.$item_title);
    $itemNode->appendChild($titleItemNode);
    // <description>を作成し、<item>に追加
    $descriptionItemNode = $dom->createElement(
                           “description”,
                           $item_description);
    $itemNode->appendChild($descriptionItemNode);
    // <link>を作成し、<item>に追加
    $linkItemNode = $dom->createElement(
                    ”link”,
                    $url.”tmp/”.urlencode(urlencode($item_title)).”.htm”);
    $itemNode->appendChild($linkItemNode);
    // <pubDate>を作成、<item>に追加
    $pubDateItemNode = $dom->createElement(
                       “pubDate”,
                       date(“D, d M Y H:i:s +0900″));
    $itemNode->appendChild($pubDateItemNode);
    // <item>タグが10個以上あるなら古い<item>を削除する
    $max = 10;
    $itemNodeList = $dom->getElementsByTagName(“item”);
    if($itemNodeList->length > $max){
      $loops = $itemNodeList->length;
      for($i=$max ;$i<=$loops; $i++){
        $delNode = $itemNodeList->item(0);
        $delNode->parentNode->removeChild($delNode);
      }
    }
    // 保存
    $dom->save( $rss_file );
  }else{
    /******************/
    /* PHP4以降の場合 */
    /******************/
    // RSSファイルが存在するか確認
    if(file_exists($rss_file)){
      // 存在する場合は読み込む
      $dom = domxml_open_file($rss_file);
      // <channel>ノード
      $channelNodeList = $dom->get_elements_by_tagname(“channel”);
      $channelNode = $channelNodeList[0];
    }else{
      // 存在しない場合は新たに作成する
      $dom = domxml_new_doc(“1.0″);
      // <rss>ルートノード
      $rssNode = $dom->create_element(“rss”);
      $rssNode->set_attribute(“version”,”2.0″);
      $dom->append_child($rssNode);
      // <channel>を作成し、<rss>に追加
      $channelNode = $dom->create_element(“channel”);
      $rssNode->append_child($channelNode);
      // <title>を作成し、<channel>に追加
      $titleNode = $dom->create_element(“title”);
      $titleNode->set_content(mb_convert_encoding($site_name,”UTF-8″));
      $channelNode->append_child( $titleNode );
      // <link>を作成し、<channel>に追加
      $linkNode = $dom->create_element(“link”);
      $linkNode->set_content($url);
      $channelNode->append_child( $linkNode );
      // <description>を作成し、<channel>に追加
      $descriptionNode = $dom->create_element(“description”);
      $descriptionNode->set_content($site_description);
      $channelNode->append_child( $descriptionNode );
      // <lastBuildDate>を作成し、<channel>に追加
      // <lastBuildDate>には、現在日時を格納する
      $lastBuildDateNode = $dom->create_element(“lastBuildDate”);
      $lastBuildDateNode->set_content(date(“D, d M Y H:i:s +0900″));
      $channelNode->append_child( $lastBuildDateNode );
      // <language>を作成し、<channel>に追加
      $languageNode = $dom->create_element(“language”);
      $languageNode->set_content(“ja”);
      $channelNode->append_child( $languageNode );
    }
    // <item>を作成し、<channel>に追加
    $itemNode = $dom->create_element(“item”);
    $channelNode->append_child($itemNode);
    // <title>を作成し、<item>に追加
    $titleItemNode = $dom->create_element(“title”);
    $titleItemNode->set_content(
                    mb_convert_encoding($site_name.” – “.$item_title,”UTF-8″));
    $itemNode->append_child($titleItemNode);
    // <description>を作成し、<item>に追加
    $descriptionItemNode = $dom->create_element(“description”);
    $descriptionItemNode->set_content(
                          mb_convert_encoding($item_description,”UTF-8″));
    $itemNode->append_child($descriptionItemNode);
    // <link>を作成し、<item>に追加
    $linkItemNode = $dom->create_element(“link”);
    $linkItemNode->set_content(
                   $url.”tmp/”.urlencode(urlencode($item_title)).”.htm”);
    $itemNode->append_child($linkItemNode);
    // <pubDate>を作成、<item>に追加
    $pubDateItemNode = $dom->create_element(“pubDate”);
    $pubDateItemNode->set_content(date(“D, d M Y H:i:s +0900″));
    $itemNode->append_child($pubDateItemNode);
    // <item>タグが10個以上あるなら古い<item>を削除する
    $max = 10;
    $itemNodeList = $dom->get_elements_by_tagname(“item”);
    if(count($itemNodeList) > $max){
      $loops = count($itemNodeList);
      for($i=$max ;$i<=$loops; $i++){
        $delNode = $itemNodeList[$i-$max];
        $parentNode = $delNode->parent_node();
        $parentNode->remove_child($delNode);
      }
    }
    // 保存
    $dom->dump_file( $rss_file );
  }
}
?>

で、↑これを実行すると、↓こんな感じのRSS(index.xml)が作成される。

<?xml version=”1.0″ ?>
<rss version=”2.0″>
  <channel>
    <title>RSSテスト用サイト</title>
    <link>http://localhost/</link>
    <description>RSS2.0保存テスト用のサイト</description>
    <lastBuildDate>Sat, 03 Nov 2007 00:27:18 +0900</lastBuildDate>
    <language>ja</language>
    <item>
      <title>RSSテスト用サイト – タイトル</title>
      <description>説明</description>
      <link>http://localhost/tmp/%25E3%2582%25BF%25E3%2582%25A4%25E3%2583%2588%25E3%2583%25AB.htm</link>
      <pubDate>Sat, 03 Nov 2007 00:27:18 +0900</pubDate>
    </item>
    <item>
      <title>RSSテスト用サイト – タイトル</title>
      <description>説明</description>
      <link>http://localhost/tmp/%25E3%2582%25BF%25E3%2582%25A4%25E3%2583%2588%25E3%2583%25AB.htm</link>
      <pubDate>Sat, 03 Nov 2007 00:54:37 +0900</pubDate>
    </item>
  </channel>
</rss>

でも、↑コレ追加された項目(<item>タグ)は、古い順に並ぶ(普通は新しい順に並ぶ)。
XSLTはソート機能はあるが、DOMはソート機能が無いので作ってません。
ちなみに、このRSS生成プログラムはくしけん用に作ったモノです。


Tagged: ,

Leave a comment

メールアドレスが公開されることはありません。

CAPTCHA


*