Exemplo n.º 1
0
/**
 * 2016-10-29
 * @param mixed[] $a
 * @return string
 */
function dfa_hashm(array $a)
{
    return md5(dfa_hash($a));
}
Exemplo n.º 2
0
/**
 * 2016-09-04
 * Не используем решения типа такого: http://stackoverflow.com/a/34711505
 * потому что они возвращают @see \Closure, и тогда кэшируемая функция становится переменной,
 * что неудобно (неунифицировано и засоряет глобальную область видимости переменными).
 * @param \Closure $f
 * Используем именно  array $a = [], а не ...$a,
 * чтобы кэшируемая функция не перечисляла свои аргументы при передачи их сюда,
 * а просто вызывала @see func_get_args()
 *
 * 2016-11-01
 * Будьте осторожны при передаче в функцию $f параметров посредством use:
 * эти параметры не будут участвовать в расчёте ключа кэша.
 *
 * @param mixed[] $a [optional]
 * @return mixed
 */
function dfcf(\Closure $f, array $a = [])
{
    /** @var array(string => mixed) $c */
    static $c = [];
    /** @var array(string => string) $b */
    $b = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];
    /**
    * 2016-09-04
    * Когда мы кэшируем статический метод, то ключ «class» присутствует,
    * а когда функцию — то отсутствует: https://3v4l.org/ehu4O
    * Ради ускорения не используем свои функции dfa() и df_cc().
    *
    * 2016-11-24
    * Когда мы кэшируем статический метод, то значением ключа «class» является не вызванный класс,
    * а тот класс, где определён кэшируемый метод: https://3v4l.org/OM5sD
    * Поэтому все потомки класса с кэшированным методом будут разделять общий кэш.
    * Поэтому если Вы хотите, чтобы потомки имели индивидуальный кэш,
    * то учитывайте это при вызове dfcf.
    * Например, пишите не так:
    			private static function sModule() {return dfcf(function() {return
    				S::convention(static::class)
    			;});}
    * а так:
    			private static function sModule() {return dfcf(function($c) {return
    				S::convention($c)
    			;}, [static::class]);}
    *
    * У нас нет возможности вычислять имя вызвавшего нас класса автоматически:
    * как уже было сказано выше, debug_backtrace() возвращает только имя класса, где метод был объявлен,
    * а не вызванного класса.
    * А get_called_class() мы здесь не можем вызывать вовсе:
    * «Warning: get_called_class() called from outside a class»
    * https://3v4l.org/ioT7c
    */
    /** @var string $k */
    $k = (!isset($b['class']) ? null : $b['class'] . '::') . $b['function'] . (!$a ? null : dfa_hash($a));
    // 2016-09-04
    // https://3v4l.org/9cQOO
    return array_key_exists($k, $c) ? $c[$k] : ($c[$k] = call_user_func_array($f, $a));
}