4.3. Zend_Cache のフロントエンド

4.3.1. Zend_Cache_Core

4.3.1.1. 導入

Zend_Cache_Core は特別なフロントエンドであり、 モジュールのコアに含まれています。これはキャッシュフロントエンドの 基本機能を実装したものであり、他のクラスによってオーバーライドされます。

[注意] 注意

その他のフロントエンドクラスは、すべて Zend_Cache_Core を継承しており、以下で説明しているメソッドおよびオプションは 他のフロントエンドでも使用可能です。そのため、ここではこれらについての 詳しい説明は省略します。

4.3.1.2. 使用可能なオプション

これらのオプションを、先の例で示したようにファクトリメソッドに渡します。

表 4.1. 使用可能なオプション

オプション データ型 デフォルト値 説明
caching boolean true キャッシングを有効/無効にします (キャッシュされたスクリプトのデバッグ時に有用です)。
lifetime int 3600 キャッシュの有効期間 (秒)。null を指定すると、有効期間が無期限となります。
logging boolean false true を指定すると、Zend_Log によるロギングが有効になります (しかし、処理速度は低下します)。
write_control boolean true 書き込み制御を有効/無効にします (壊れたエントリを検出するため、 書き込んだ直後にそのキャッシュを読み込みます)。 writeControl を有効にすると、キャッシュの書き込みがやや遅くなりますが、 読み込みの速度は変わりません (これはキャッシュファイルが壊れているかどうかを調べるものですが、 完全に判断できるわけではありません)。
automatic_serialization boolean false 自動シリアライズを有効/無効にします。 文字列でないデータを直接保存する際に使用します (しかし、処理速度は低下します)。
automatic_cleaning_factor int 10 自動クリーンアッププロセス (ガベージコレクタ) の設定を行います。 0 を指定すると、自動キャッシュクリーニングを行いません。 1 を指定すると計画的にキャッシュのクリーニングを行い、また x (1 より大きな整数) を指定すると、 x 回のキャッシュ書き込みについて 1 回の頻度で ランダムに自動クリーニングを行います。

4.3.1.3. 例

マニュアルのいちばんはじめのほうに、例を示しています。

もしキャッシュに文字列しか保存しないのなら ("automatic_serialization" オプションを使用すると boolean も保存できるので)、 このようにもう少しコンパクトに作成することが可能です。

<?php  
             
// すでに $cache が存在するものとします

$id = 'myBigLoop'; //「キャッシュしたい内容」のキャッシュ ID

if (!($data = $cache->load($id))) {
    // キャッシュが存在しませんでした
    
    $data = '';
    for ($i = 0; $i < 10000; $i++) {
        $data = $data . $i;
    }
    
    $cache->save($data);
    
} 

// [...] $data を用いて何かをします (echo したり、何かに渡したりなど)
             
?>       

複数のブロックやデータのインスタンスをキャッシュしたい場合も、考え方は同じです。

<?php  
             
// 一意な ID を使用するようにしましょう
$id1 = 'foo';
$id2 = 'bar';

// ブロック 1
if (!($data = $cache->load($id1))) {
    // キャッシュが存在しませんでした
    
    $data = '';
    for ($i=0;$i<10000;$i++) {
        $data = $data . $i;
    }
    
    $cache->save($data);
    
} 
echo($data);

// これは、キャッシュ処理の影響を受けません
echo('キャッシュされません !');

// ブロック 2
if (!($data = $cache->load($id2))) {
    // キャッシュが存在しませんでした
    
    $data = '';
    for ($i=0;$i<10000;$i++) {
        $data = $data . '!';
    }
    
    $cache->save($data);
    
} 
echo($data);

?>       

4.3.2. Zend_Cache_Frontend_Output

4.3.2.1. 導入

Zend_Cache_Frontend_Output は、出力を横取りするフロントエンドです。 これは PHP の出力バッファリング処理を使いやすくしたもので、 start() メソッドと end() メソッドの間の出力を横取りします。

4.3.2.2. 使用可能なオプション

Zend_Cache_Core のオプション以外に、 このフロントエンドが独自に使用するオプションはありません。

4.3.2.3. 例

このマニュアルの冒頭に示した例とほとんど同じですが、少しだけ変更を加えています。

<?php

// キャッシュが見つからなかった場合に、出力バッファリングが起動します
if (!($cache->start('mypage'))) {

    // すべてをいつもどおりに出力しますoutput everything as usual
    echo 'Hello world! ';
    echo 'これはキャッシュされます ('.time().') ';

    $cache->end(); // 出力バッファリングを終了します

}

echo 'これはキャッシュされません ('.time().')';

?>       

この形式を使用すると、既存のプロジェクトに簡単に出力キャッシュ処理を追加することができます。 コードのリファクタリングもほとんど行わずにすませられるでしょう。

4.3.3. Zend_Cache_Frontend_Function

4.3.3.1. 導入

Zend_Cache_Frontend_Function は、関数コールの結果をキャッシュします。 call() というメソッドを保持しており、 関数名とパラメータを配列にしてこのメソッドに渡します。

4.3.3.2. 使用可能なオプション

表 4.2. 使用可能なオプション

オプション データ型 デフォルト値 説明
cacheByDefault boolean true true の場合は、関数のコール結果がデフォルトでキャッシュされます。
cachedFunctions array   常にキャッシュされる関数の名前。
nonCachedFunctions array   決してキャッシュされない関数の名前。

4.3.3.3. 例

call() 関数の使用法は、PHP の call_user_func_array() と同じです。

<?php

$cache->call('veryExpensiveFunc', $params);

# $params は配列です。
# 例えば、veryExpensiveFunc(1, 'foo', 'bar') のコールをキャッシュするには
# $cache->call('veryExpensiveFunc', array(1, 'foo', 'bar')) とします。

?>       

Zend_Cache_Frontend_Function は、 関数の返り値だけでなく関数内部での出力もキャッシュします。

[注意] 注意

array()echo()empty()eval()exit()isset()list()print() および unset() 以外なら、 任意の組み込み関数やユーザ定義関数を渡すことができます。

4.3.4. Zend_Cache_Frontend_Class

4.3.4.1. 導入

Zend_Cache_Frontend_Class は、Zend_Cache_Frontend_Function と異なり、オブジェクトおよびスタティックメソッドのコールをキャッシュします。

4.3.4.2. 使用可能なオプション

表 4.3. 使用可能なオプション

オプション データ型 デフォルト値 説明
cachedEntity (必須) mixed   クラス名を設定すると、抽象クラスおよびスタティックコールをキャッシュします。 オブジェクトを設定すると、そのオブジェクトのメソッドをキャッシュします。
cacheByDefault boolean true true を設定すると、デフォルトでキャッシュされます。
cachedMethods array   常にキャッシュされるメソッドの名前。
nonCachedMethods array   決してキャッシュされないメソッドの名前。

4.3.4.3. 例

例えば、スタティックメソッドのコールをキャッシュするには次のようにします。

<?php

class test {
   
    # スタティックメソッド
    public static function foobar($param1, $param2) {
        echo "foobar_output($param1, $param2)";
        return "foobar_return($param1, $param2)";   
    }

}

// [...]
$frontendOptions = array(
    'cachedEntity' => 'test' // クラス名を指定します
);
// [...]

# これはキャッシュされます
$res = $cache->foobar('1', '2');

?>       

通常のメソッドのコールをキャッシュするには次のようにします。

<?php

class test {
   
    private $_string = 'hello !';
      
    public function foobar2($param1, $param2) {
        echo($this->_string);
        echo "foobar2_output($param1, $param2)";
        return "foobar2_return($param1, $param2)";   
    }

}

// [...]
$frontendOptions = array(
    'cachedEntity' => new test() // クラスのインスタンスを指定します
);
// [...]

# これはキャッシュされます
$res = $cache->foobar2('1', '2');

?>       

4.3.5. Zend_Cache_Frontend_File

4.3.5.1. 導入

Zend_Cache_Frontend_File は、マスタファイルの 「更新時刻」にもとづいて動作するフロントエンドです。 これは、例えば設定ファイルやテンプレートなどで有効に使えるでしょう。

例えば、XML の設定ファイルを使用しており、それが「設定オブジェクト」 (Zend_Config など) を返す関数でパースされるとしましょう。 Zend_Cache_Frontend_File を使用すると、その「設定オブジェクト」 をキャッシュすることができ (これにより、 XML ファイルを毎回パースする必要がなくなります)、さらに「マスタファイル」 との間で強力な依存性を保持することができます。そのため、XML 設定ファイルが更新されると、即時にキャッシュが無効になります。

4.3.5.2. 使用可能なオプション

表 4.4. 使用可能なオプション

オプション データ型 デフォルト値 説明
masterFile (必須) string マスタファイルへのフルパス。

4.3.5.3. 例

このフロントエンドの使用法は Zend_Cache_Core と同じです。 そのため、特に例は用意していません。唯一しなければならないことは、 ファクトリを使用する際に、バックエンドのオプションとして masterFile を設定することだけです。

4.3.6. Zend_Cache_Frontend_Page

4.3.6.1. 導入

Zend_Cache_Frontend_PageZend_Cache_Frontend_Output と似ていますが、ページ全体をキャッシュする目的で設計されています。 Zend_Cache_Frontend_Page を使用して、 ページの一部だけをキャッシュすることはできません。

一方、「キャッシュ ID」は自動的に生成されます。この ID は、 $_SERVER['REQUEST_URI'] および (オプションの設定によっては) $_GET$_POST$_SESSION$_COOKIE$_FILES をもとにして生成されます。 さらに、ひとつのメソッド (start()) をコールするだけで使用できます。 end() は、ページの終了時に自動的にコールされます。

現時点ではまだ実装されていませんが、将来は HTTP conditional システムを追加する予定です。 これにより、ネットワークの帯域を節約できるようになります (キャッシュにヒットし、かつブラウザがそのバージョンを既に持っている場合に HTTP 304 Not Modified を送信するようにします)。

4.3.6.2. (Zend_Cache ファクトリで、このフロントエンドを使用する際に) 使用可能なオプション

表 4.5. 使用可能なオプション

オプション データ型 デフォルト値 説明
http_conditional boolean false http_conditional システムを使用します (現時点ではまだ実装されていません)。
debug_header boolean false true の場合は、キャッシュされた各ページの先頭に デバッグ用テキストが追加されます。
default_options array array(...説明を参照ください...) デフォルトのオプションを表す連想配列です。
  • (boolean, デフォルトは true) cache : true の場合はキャッシュが有効になります。

  • (boolean, デフォルトは false) cache_with_get_variables : true の場合は、$_GET 配列に変数が含まれていてもキャッシュがオンのままになります。

  • (boolean, デフォルトは false) cache_with_post_variables : true の場合は、$_POST 配列に変数が含まれていてもキャッシュがオンのままになります。

  • (boolean, デフォルトは false) cache_with_session_variables : true の場合は、$_SESSION 配列に変数が含まれていてもキャッシュがオンのままになります。

  • (boolean, デフォルトは false) cache_with_files_variables : true の場合は、$_FILES 配列に変数が含まれていてもキャッシュがオンのままになります。

  • (boolean, デフォルトは false) cache_with_cookie_variables : true の場合は、$_COOKIE 配列に変数が含まれていてもキャッシュがオンのままになります。

  • (boolean, デフォルトは true) make_id_with_get_variables : true の場合は、キャッシュ ID が $_GET 配列の内容に依存するようになります。

  • (boolean, デフォルトは true) make_id_with_post_variables : true の場合は、キャッシュ ID が $_POST 配列の内容に依存するようになります。

  • (boolean, デフォルトは true) make_id_with_session_variables : true の場合は、キャッシュ ID が $_SESSION 配列の内容に依存するようになります。

  • (boolean, デフォルトは true) make_id_with_files_variables : true の場合は、キャッシュ ID が $_FILES 配列の内容に依存するようになります。

  • (boolean, デフォルトは true) make_id_with_cookie_variables : true の場合は、キャッシュ ID が $_COOKIE 配列の内容に依存するようになります。

regexps array array() 特定の REQUEST_URI に対してのみ適用するオプションを設定する連想配列です。 キーが (PCRE の) 正規表現、対応する値は連想配列となります。 この連想配列には、正規表現が $_SERVER['REQUEST_URI'] にマッチした場合に設定されるオプションを設定します (使用可能なオプションについては default_options を参照ください)。 複数の正規表現が $_SERVER['REQUEST_URI'] にマッチした場合は、 一番最後にマッチしたもののみが使用されます。

4.3.6.3. 例

Zend_Cache_Frontend_Page の使用法は、きわめて簡単です。

<?php
               
// [...] // require、設定そしてファクトリ
    
$cache->start();
// キャッシュにヒットした場合はその結果がブラウザに送信され、処理はここで停止します
    
// ページの残りの部分 ...
    
?>       

もう少し複雑な例を見てみましょう。これは、起動ファイル (例えば Zend_Controller など) 内でキャッシュを集中管理する方法を示したものです。

<?php

// [...] キャッシュセクションの前には、あまり多くの行を書かないようにしましょう。
// [...] 例えば、処理速度を最適化するためには "require_once" や "Zend_Loader::loadClass"
// [...] をキャッシュセクションの後におくべきです。

require_once 'Zend/Cache.php';

$frontendOptions = array(
   'lifetime' => 7200,
   'debug_header' => true, // デバッグします
   'regexps' => array(
       '^/$' => array('cache' => true),         // IndexController 全体をキャッシュします
       '^/index/' => array('cache' => true),    // IndexController 全体をキャッシュします
       '^/article/' => array('cache' => false), // ArticleController はキャッシュしません
       '^/article/view/' => array(              // ……が、ArticleController の "view" アクションは
           'cache' => true,                     // キャッシュします。また、たとえ $_POST に何らかの
           'cache_with_post_variables' => true,    // 変数が含まれていてもキャッシュを行います
           'make_id_with_post_variables' => true,   // (しかし、そのキャッシュは $_POST 配列に依存します)。
       )
   )      
);
$backendOptions = array(
    'cache_dir' => '/tmp/' 
);

// Zend_Cache_Frontend_Page オブジェクトを取得します
$cache = Zend_Cache::factory('Page', 'File', $frontendOptions, $backendOptions);

$cache->start();
// キャッシュにヒットした場合はその結果がブラウザに送信され、スクリプトの処理はここで停止します。

// [...] 起動ファイルの終点 (これらの行は、キャッシュにヒットした場合は実行されません)。
                
?>