2020/10/3 このブログを更地に戻しました。過去にもらったコメントはいずれ復元します。
PEAR

PEAR Cache_LiteでXMLをキャッシュ保存するPHPスクリプト

PEAR

手軽に使えそうだったSimplePieはRSS形式のXMLファイルしか扱えなかったので、PEARのCache_Liteを使ってXMLデータをファイルキャッシュ方式で保存するPHPスクリプトを書いてみた。PHPに向き合うのは数年以上ぶりなので、たったこれだけでも結構苦労した。

独学の自己流なので、この書き方で合っているのか分からない。知らない。素人のDIYだ!

PEAR Cache_LiteでXMLをファイルキャッシュとして保存するPHPスクリプト

PEARはPHPスクリプトのライブラリーなので、全てをインストールしなくても、使いたい機能のパッケージだけ公式サイトからダウンロードして個別に利用することができる。

PEAR Cache_Liteのダウンロード

Cache_Lite

PEAR Cache_Liteを利用すると、MySqlなどのデータベースを使わずにファイル形式でデータをキャッシュ保存できる。データ検索をするのには向いてないけれど、外部から取得したデータを一定期間保存するのに向いている。

データベースを使わないので、PHPが動くだけのサーバーでも利用できる。

設置

├ /Cache/
│└ Lite.php …PEAR Cache_Liteのphpファイル
├ /tmp/ …キャッシュ保存用ディレクトリ
└ index.php …このPHPスクリプト
<?php

// Include the package
require_once('Cache/Lite.php');

//取得・キャッシュするxmlのurl
$xml_url = 'https://www.drk7.jp/weather/xml/01.xml';    // https://www.drk7.jp/weather/


//実行 キャッシュ保存3秒
$result = get_data($xml_url,3);

//結果表示
echo '<pre>';var_dump($result);echo '</pre>';


//ファイルキャッシュ
//xmlのURLを送るとxmlのオブジェクトが戻る
function get_data($xml_url, $lifetime = 3600){

    // Set a few options
    // https://pear.plus-server.net/package.caching.cache-lite.cache-lite.cache-lite.html
    $options = array(
        //キャッシュディレクトリ
        'cacheDir'        => 'tmp/',
        //キャッシュタイム秒
        'lifeTime'        => $lifetime,
        //エラーモード
        'pearErrorMode'        => CACHE_LITE_ERROR_DIE,
        //メモリキャッシュにストアするレコードの最大数
        'memoryCachingLimit'    => 10000,
        //ハッシュ化されたディレクトリ構造のレベル
        'hashedDirectoryLevel'    => 2
    );

    // Create a Cache_Lite object
    $Cache_Lite = new Cache_Lite($options);

    // Test if thereis a valide cache for this id
    if ($cache_data = $Cache_Lite->get($xml_url)) {
        //true キャッシュ取得成功

        return simplexml_load_string($cache_data);

    } else { // No valid cache found (you have to make the page)
        //false キャッシュ取得失敗
        //xmlデータを文字列で取得
        $new_data = file_get_contents($xml_url);
        //キャッシュとして保存
        $Cache_Lite->save($new_data);

        return simplexml_load_string($new_data);

    }//if
}//function cache

?>

スクリプトの解説

  1. XMLのURLを指定する
  2. 「XMLのURL」をIDにしてキャッシュを探す。
    1. キャッシュがある場合、simplexml_load_string()でデータ文字列をXMLオブジェクトに変換して返す。
    2. キャッシュがない場合、file_get_contents()でURLからXMLを文字列として取得し、「XMLのURL」をIDにして、キャッシュに保存。
      simplexml_load_string()でデータ文字列をXMLオブジェクトに変換して返す。

ちゃんとキャッシュファイルが作成・更新されているかをFTPソフトで確認したいので、保存期間を3秒にしてある。

Cache_Lite_File::getの挙動メモ

  1. キャッシュ保存期間10分で利用
  2. 新規保存される
  3. 1分後にキャッシュ保存期間10分で利用
  4. 新規保存されず(キャッシュ読み込み)
  5. 2分後にキャッシュ保存期間1分で利用
  6. 新規保存される(1.のキャッシュを上書き)

つまり'lifeTime'は保存するキャッシュファイルの未来に向けての保存期間ではなく、同じキャッシュファイルがすでに存在する場合に上書きするか否かの判断として過去に遡って使われる(自動クリーニングプロセスを利用しない場合)。

つまづいた点

キャッシュ用ディレクトリをPEARのサンプルの通り '/tmp/' にしたにもかかわらず、キャッシュファイルが生成されなかった(なのにちゃんと動くのが謎だった)。そこで先頭のスラッシュを取り除いた 'tmp/' または先頭にドットを付けた './tmp/' にしたらちゃんとキャッシュファイルが作成されるようになった。

なんなんだ。

参考

PEARマニュアル Cache_Lite

公式サイト(英語)

Manual :: Cache_Lite

日本語版(アーカイブ)

Manual :: Cache_Lite

PHPマニュアル

file_get_contents()

ファイルの内容を全て文字列に読み込む

PHP: file_get_contents - Manual

simplexml_load_string()

XML 文字列をオブジェクトに代入する

PHP: simplexml_load_string - Manual

simplexml_load_file()を使えばXMLのURLからXMLオブジェクトとして取得することが出来るけど、PEAR Cache_Liteに文字列として保存したいので取得はfile_get_contents()で行っている。

コメント

タイトルとURLをコピーしました