Пример #1
0
 /**
  * 関数を呼び出す
  *
  * 関数名と引数から決定されるキーに対応する値がKVSにキャッシュされていれば
  * それを返し、なければ関数を呼び出し、結果をKVSにキャッシュする。
  *
  * @param callable $function
  * @param array $parameters
  * @return mixed
  * @throws InvalidArgumentException
  */
 public function invoke($function, array $parameters = array())
 {
     if (!is_callable($function)) {
         throw new InvalidArgumentException('Non-callable value was given');
     }
     // 関数名
     if (is_string($function)) {
         $name = $function;
         if (strpos($function, '::') !== false) {
             $function = explode('::', $function, 2);
         }
     } elseif (is_object($function)) {
         $name = get_class($function) . '->__invoke';
     } elseif (is_object($function[0])) {
         $name = get_class($function[0]) . '->' . $function[1];
     } else {
         $name = $function[0] . '::' . $function[1];
     }
     // キー
     $key = strtolower($name) . '(';
     if ($n = count($parameters)) {
         $key .= $n . ':' . md5(serialize($parameters));
     } else {
         $key .= 'void';
     }
     $key .= ')';
     // キャッシュを取得
     $record = $this->_kvs->getRaw($key);
     if ($record && !$record->isExpired($this->_lifeTime)) {
         return $this->_kvs->getCodec()->decodeValue($record->value);
     }
     // なければ関数を実行
     if ($n) {
         if ($n == 1 && !is_array($function)) {
             $value = $function(reset($parameters));
         } else {
             $value = call_user_func_array($function, $parameters);
         }
     } elseif (is_array($function)) {
         $value = call_user_func($function);
     } else {
         $value = $function();
     }
     // キャッシュに保存
     if ($record) {
         $this->_kvs->update($key, $value);
     } else {
         $this->_kvs->set($key, $value);
     }
     return $value;
 }