public static function assertCallback($callback, $callee, $parameterPosition)
{
if (!is_callable($callback)) {
if (!is_array($callback) && !is_string($callback)) {
throw new static(sprintf('%s() expected parameter %d to be a valid callback, no array, string, closure or functor given', $callee, $parameterPosition));
}
$type = gettype($callback);
switch ($type) {
case 'array':
$type = 'method';
$callback = array_values($callback);
$sep = '::';
if (is_object($callback[0])) {
$callback[0] = get_class($callback[0]);
$sep = '->';
}
$callback = join($callback, $sep);
break;
default:
$type = 'function';
break;
}
throw new static(sprintf("%s() expects parameter %d to be a valid callback, %s '%s' not found or invalid %s name", $callee, $parameterPosition, $type, $callback, $type));
}
}
/** * Memoizes callbacks and returns their value instead of calling them * * @param callable $callback Callable closure or function * @param array $arguments Arguments * @param array|string $key Optional memoize key to override the auto calculated hash * @return mixed */ function memoize($callback, array $arguments = array(), $key = null) { static $storage = array(); if ($callback === null) { $storage = array(); return null; } InvalidArgumentException::assertCallback($callback, __FUNCTION__, 1); static $keyGenerator = null; if (!$keyGenerator) { $keyGenerator = function ($value) use(&$keyGenerator) { $type = gettype($value); if ($type === 'array') { $key = join(':', map($value, $keyGenerator)); } elseif ($type === 'object') { $key = get_class($value) . ':' . spl_object_hash($value); } else { $key = (string) $value; } return $key; }; } if ($key === null) { $key = $keyGenerator(array_merge(array($callback), $arguments)); } else { $key = $keyGenerator($key); } if (!isset($storage[$key]) && !array_key_exists($key, $storage)) { $storage[$key] = call_user_func_array($callback, $arguments); } return $storage[$key]; }