MediaWiki  master
MemoizedCallable.php
Go to the documentation of this file.
1 <?php
44 
46  private $callable;
47 
49  private $callableName;
50 
52  private $ttl;
53 
58  public function __construct( $callable, $ttl = 3600 ) {
59  if ( !is_callable( $callable, false, $this->callableName ) ) {
60  throw new InvalidArgumentException(
61  'Argument 1 passed to MemoizedCallable::__construct() must ' .
62  'be an instance of callable; ' . gettype( $callable ) . ' given'
63  );
64  }
65 
66  if ( $this->callableName === 'Closure::__invoke' ) {
67  throw new InvalidArgumentException( 'Cannot memoize unnamed closure' );
68  }
69 
70  $this->callable = $callable;
71  $this->ttl = min( max( $ttl, 1 ), 86400 );
72  }
73 
81  protected function fetchResult( $key, &$success ) {
82  $success = false;
83  if ( function_exists( 'apcu_fetch' ) ) {
84  return apcu_fetch( $key, $success );
85  }
86  return false;
87  }
88 
95  protected function storeResult( $key, $result ) {
96  if ( function_exists( 'apcu_store' ) ) {
97  apcu_store( $key, $result, $this->ttl );
98  }
99  }
100 
108  public function invokeArgs( array $args = [] ) {
109  foreach ( $args as $arg ) {
110  if ( $arg !== null && !is_scalar( $arg ) ) {
111  throw new InvalidArgumentException(
112  'MemoizedCallable::invoke() called with non-scalar ' .
113  'argument'
114  );
115  }
116  }
117 
118  $hash = md5( serialize( $args ) );
119  $key = __CLASS__ . ':' . $this->callableName . ':' . $hash;
120  $success = false;
121  $result = $this->fetchResult( $key, $success );
122  if ( !$success ) {
123  $result = ( $this->callable )( ...$args );
124  $this->storeResult( $key, $result );
125  }
126 
127  return $result;
128  }
129 
138  public function invoke( ...$params ) {
139  return $this->invokeArgs( $params );
140  }
141 
151  public static function call( $callable, array $args = [], $ttl = 3600 ) {
152  $instance = new self( $callable, $ttl );
153  return $instance->invokeArgs( $args );
154  }
155 }
$success
APCu-backed function memoization.
static call( $callable, array $args=[], $ttl=3600)
Shortcut method for creating a MemoizedCallable and invoking it with the specified arguments.
invoke(... $params)
Invoke the memoized function or method.
__construct( $callable, $ttl=3600)
fetchResult( $key, &$success)
Fetch the result of a previous invocation.
invokeArgs(array $args=[])
Invoke the memoized function or method.
storeResult( $key, $result)
Store the result of an invocation.