spl_object_hash for PHP <5.2(对象实例的唯一ID)

Row*_*wan 5 php spl

我正在尝试在PHP 5+中获取对象实例的唯一ID.

该函数spl_object_hash()可从PHP 5.2获得,但我想知道是否有旧的PHP版本的解决方法.

php.net上的评论中有几个函数,但它们并不适合我.第一个(简化):

function spl_object_hash($object){
    if (is_object($object)){
        return md5((string)$object);
        }
    return null;
    }
Run Code Online (Sandbox Code Playgroud)

不适用于本机对象(如DOMDocument),第二个:

function spl_object_hash($object){
    if (is_object($object)){
        ob_start();
        var_dump($object);
        $dump = ob_get_contents();
        ob_end_clean();
        if (preg_match('/^object\(([a-z0-9_]+)\)\#(\d)+/i', $dump, $match)) {
            return md5($match[1] . $match[2]);
            }
        }
    return null;
    }
Run Code Online (Sandbox Code Playgroud)

看起来它可能是一个主要的性能破坏者!

有人有什么东西吗?

bob*_*cow 4

我进行了一些快速测试。我真的认为你最好使用bind('evt_name', array($obj, 'callback_function')). 如果您绝对想采用 spl_object_hash 路线,而不是使用事件绑定存储引用,那么您将看到如下所示的内容:

var_dump / extract 和 hash id 实现:

function spl_object_hash_var_dump($object){
    if (is_object($object)){
        ob_start();
        var_dump($object);
        $dump = ob_get_contents();
        ob_end_clean();
        if (preg_match('/^object\(([a-z0-9_]+)\)\#(\d)+/i', $dump, $match)) {
            return md5($match[1] . $match[2]);
            }
        }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

一个简单的引用实现:

function spl_object_dumb_references(&$object) {
    static $hashes;

    if (!isset($hashes)) $hashes = array();

    // find existing instance
    foreach ($hashes as $hash => $o) {
        if ($object === $o) return $hash;
    }

    $hash = md5(uniqid());
    while (array_key_exists($hash, $hashes)) {
        $hash = md5(uniqid());
    }

    $hashes[$hash] = $object;
    return $hash;
}
Run Code Online (Sandbox Code Playgroud)

这个基本上比基于类的参考函数差 5-50 倍,所以不值得担心。

按类实现存储引用:

function spl_object_hash_references(&$object) {
    static $hashes;

    if (!isset($hashes)) $hashes = array();

    $class_name = get_class($object);
    if (!array_key_exists($class_name, $hashes)) {
        $hashes[$class_name] = array();
    }

    // find existing instance
    foreach ($hashes[$class_name] as $hash => $o) {
        if ($object === $o) return $hash;
    }

    $hash = md5(uniqid($class_name));
    while (array_key_exists($hash, $hashes[$class_name])) {
        $hash = md5(uniqid($class_name));
    }

    $hashes[$class_name][$hash] = $object;
    return $hash;
}
Run Code Online (Sandbox Code Playgroud)

你最终会得到如下所示的结果。摘要:基于类的引用实现在 n/50 个类左右性能最佳——在最佳状态下,它的性能仅为var_dump基于类的实现的 1/3,而且通常要差得多

var_dump实施似乎是可以忍受的,但并不理想。但如果您没有进行太多此类查找,那么它不会成为您的瓶颈。特别是作为 PHP < 5.2 boxen 的后备。