Php 如何计算可调用函数的唯一哈希

Php 如何计算可调用函数的唯一哈希,php,Php,我正在尝试编写一个记忆函数,我刚刚意识到当回调不是一个简单的字符串时,它不起作用。例如,PHP可以接受数组($this,'memberFunc')形式的回调,这不适合序列化 然后我意识到我们其实并不想对整个回调函数/对象进行散列/序列化,我们只需要一个唯一的ID,这样我们就可以检查引用是否相等。我原以为spl\u object\u hash可以解决这个问题,但它对数组不起作用 是否有其他方法为可调用对象生成唯一的引用ID?出于哈希目的,您始终可以强制转换到对象: <?php class

我正在尝试编写一个记忆函数,我刚刚意识到当回调不是一个简单的字符串时,它不起作用。例如,PHP可以接受
数组($this,'memberFunc')
形式的回调,这不适合序列化

然后我意识到我们其实并不想对整个回调函数/对象进行散列/序列化,我们只需要一个唯一的ID,这样我们就可以检查引用是否相等。我原以为
spl\u object\u hash
可以解决这个问题,但它对数组不起作用


是否有其他方法为可调用对象生成唯一的引用ID?

出于哈希目的,您始终可以强制转换到对象:

<?php

class Foo{
    public function __construct(){
        $foo = array($this,'memberFunc');

        var_dump( spl_object_hash((object)$foo) );
        var_dump( spl_object_hash((object)$foo) );
    }
}

new Foo;

我编写此函数是为了获取可调用项的哈希值,具体如下:

/**
 * @param callable $func
 * @return string Unique string identifier for callable instance
 * @throws Exception
 */
private static function callable_hash($func) {
    if(!is_callable($func)) throw new Exception("Function must be a callable");
    if(is_string($func)) {
        return $func;
    } elseif(is_array($func)) {
        if(count($func) !== 2) throw new Exception("Array-callables must have exactly 2 elements");
        if(!is_string($func[1])) throw new Exception("Second element of array-callable must be a string function name");
        if(is_object($func[0])) return spl_object_hash($func[0]).'::'.$func[1];
        elseif(is_string($func[0])) return implode('::',$func);
        throw new Exception("First element of array-callable must be a class name or object instance");
    } elseif(is_object($func)) {
        return spl_object_hash($func);
    }
    throw new Exception("Unhandled callable type");
}

但如果阿尔瓦罗的解决方案有效。。。这更简单、更灵活。

根据阿尔瓦罗的回答,我提出了以下两个功能:

function memoized() {
    static $cache = array();
    $args = func_get_args();
    $func = array_shift($args);
    $key = sha1(serialize(array_merge(array(spl_object_hash((object)$func)),$args)));
    if(!isset($cache[$key])) {
        $cache[$key] = call_user_func_array($func, $args);
    }
    return $cache[$key];
}

function memoized_func($func) {
    return function() use ($func) {
        static $cache = array();
        $args = func_get_args();
        $key = sha1(serialize($args));
        if(!isset($cache[$key])) {
            $cache[$key] = call_user_func_array($func, $args);
        }
        return $cache[$key];
    };
}
用法:

$f = function($n) {
    for($i=0; $i<$n; ++$i);
    return $n;
};

$result = memoized($f,50000);
$func = memoized_func($f);
$result2 = $func(50000);
$f=函数($n){

对于($i=0;$iI)来说,解决方案可能是创建一个定义了_-toString()方法和_-call()的类方法定义为执行回调试图执行的任何操作?但这对我来说似乎真的很不正常。这是否回答了您的问题?请记住,spl\u object\u哈希每次执行都返回一个唯一的哈希值。如果将其删除或在下一次执行中,它可能会更改。实际上,此答案不起作用。如果按F5,哈希值不同,因此出于缓存目的他的休息。@TomasVotruba这是因为
spl\u object\u hash()
的工作方式,
(object)
cast不会改变这种行为。我不建议将这种函数用于缓存,因为缓存本身就是一个问题家族。