サンプルコード – Cache_Lite のファクトリメソッド(マルチユーザ対応)

Cache_Lite は大変便利なのですが、Linux/BSD などで、複数実行ユーザが同じ cacheDir (たとえば /tmp/ )を使った場合に、他ユーザが作ったキャッシュへのアクセス権限が得られないため正しく動作しません。
Cache_Lite の hashedDirectoryUmask オプションと umask() 関数で 0777 を指定すれば十分な権限が得られますが、キャッシュの盗聴やかいざんの可能性が出てくるためセキュリティ的によろしくありません。
 
簡単な対応として思い付くのは

‘cacheDir’ => ‘~/tmp’,

のようにユーザのホームディレクトリにフォルダを分けてやることですが、
今回はより汎用的にするため、ファクトリメソッド内部でユーザ判別をしてフォルダを分けることでマルチユーザ対応させてみました。
 
# 暫定的な実装なので、不備があるかもしれません。

// This source is made available under the terms of the BSD license.
 
/**
 * Cache_Lite 用汎用ファクトリメソッド。
 * (PHP 4, 5 対応)
 * @version 2007-11-08
 */
class CacheLiteFactory {
  /**
   * @access private
   */
  function CacheLiteFactory(){
      // no-op
  }
  /**
   * static.
   * @access private
   * @param array $newOptions
   * @return options
   */
  function _defaultOptions($newOptions = null){
     // 初期デフォルト設定
     static $defaultOptions = array(
         // 必要なら設定可。
      );
      if(!empty($newOptions)){
          $defaultOptions = $newOptions;
      }
      return $defaultOptions;
  }
  
   /**
    * インスタンス化に使うデフォルトのオプションを設定します。
    * 過去に設定していたオプションは全て消去されます。
    * 一部のオプションのみ追加、変更したい場合は getDefaultOption() で現在のデフォルトオプションを取得して再設定してください。
    *
    * static
    * @access public
    * @param array $newOptions 置き換えるオプション
    * @return void
    */
   function setDefaultOptions($newOptions){
      CacheLiteFactory::_defaultOptions($newOptions);
   }
   
   /**
    * インスタンス化に使われるデフォルトのオプションを取得します。
    * static
    * @access public
    * @return array 現在設定されているデフォルトのオプション
    */
   function getDefaultOptions(){
      return CacheLiteFactory::_defaultOptions();
   }
  
  /**
   * Cache_Lite インスタンスを取得する。
   * 引数を指定した場合、デフォルトオプションをベースに引数のオプションを追加,変更します。
   *
   * static
   * @access public
   * @param array $overrideOptions 上書きするオプションの連想配列
   * @return Cache_Lite
   */
   function factory($overrideOptions = array()){
       require_once “Cache/Lite.php”;
       // デフォルト値。
       $options = CacheLiteFactory::getDefaultOptions();
       
       if($overrideOptions && is_array($overrideOptions)){
            $options = array_merge($options, $overrideOptions);
       }
       if(empty($options[‘cacheDir’])){
           $options[‘cacheDir’] = “/tmp/”;
       }
        
       // 他ユーザのキャッシュはアクセス権限が十分にない(umask 0777 にしても削除はできない)ので
       // posix_getuid() で uid が取得できる場合はユーザごとにフォルダを分けるようにしておく。
      // ※ Windows 環境または –disable-posix オプション付きでビルドした場合は取得できないことに留意
       if(function_exists(“posix_getuid”)){
           if(@mkdir($options[‘cacheDir’], 0777)){ // PHP4 互換のため recursive なし
               @chmod($options[‘cacheDir’], 0777);
           }
           $options[‘cacheDir’].=”cache_uid_”.posix_getuid().DIRECTORY_SEPARATOR;
       }
       @mkdir($options[‘cacheDir’]); // PHP4 互換のため recursive はなし
       return new Cache_Lite($options);
    }
}

 

// 用例
/* —
  // デフォルトを与えるかは任意
CacheLiteFactory::setDefaultOptions(array(
    // ‘cacheDir’=>’/path/to/tmp/’,
    ‘lifeTime’ => 24 * 60 * 60, // set 1 day by default
    ‘hashedDirectoryLevel’ => 1,
    ‘automaticCleaningFactor’=>100,
  ));
— */
 
$cache = CacheLiteFactory::factory();
$value = $cache->get(“foo”);
if($value === false){
  $value = date(‘Y/m/d H:i:s’);
  $cache->save($value);
}
echo $value . “\n”;