Question

Je suis en train d'obtenir des identifiants uniques pour les instances d'objet en PHP 5 +.

La fonction, spl_object_hash() est disponible à partir de PHP 5.2 mais je me demande s'il existe une solution pour les versions PHP plus.

Il y a deux fonctions dans les commentaires sur php.net mais ils ne travaillent pas pour moi. Le premier (simplifié):

function spl_object_hash($object){
    if (is_object($object)){
        return md5((string)$object);
        }
    return null;
    }

ne fonctionne pas avec des objets natifs (tels que DOMDocument), et le second:

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;
    }

ressemble à cela pourrait être une grande performance buster!

Quelqu'un at-il quoi que ce soit dans leur manche?

Était-ce utile?

La solution

J'ai couru quelques tests rapides. Je pense vraiment que vous feriez mieux de stocker la fonction callback réelle dans votre bind () à l'aide bind('evt_name', array($obj, 'callback_function')). Si vous voulez absolument aller la route spl_object_hash, plutôt que de stocker des références avec les liaisons d'événements, vous cherchez quelque chose comme ceci:

Un var_dump / extrait et id de hachage mise en œuvre:

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;
}

références naïves mise en œuvre:

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;
}

Celui-ci était essentiellement 5-50x pire que la fonction de référence basée sur les classes à travers le conseil d'administration, il ne vaut pas se soucier.

références de magasin par la mise en œuvre de la classe:

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;
}

Et vous vous retrouvez avec qui ressemblent à cette . Résumé: la classe à base mise en œuvre des références fonctionne mieux autour de n / 50 classes - à son meilleur, il parvient à retirer un tiers l'exécution de la mise en œuvre à base de var_dump, et il est généralement beaucoup pire <. / p>

La mise en œuvre de var_dump semble être tolérable, mais pas idéal. Mais si vous ne faites pas trop de ces recherches, il ne sera pas un goulot d'étranglement pour vous. Surtout comme solution de repli pour PHP <5.2 bécanes.

Autres conseils

J'ai écrit une fonction d'assistance pour un wordpress qui offre hachage unique par objet, il fonctionne avec un compteur et stocke le hachage par comme une propriété de classe publique si elle a été affectée à un objet. L'exemple suivant illustre ceci:

/**
 * get object hash
 *
 * Returns a unique hash per object.
 *
 * Proxy function for wordpress installments on servers
 * with a PHP version < 5.2.0.
 *
 * @since 3.0.2
 * @note Become deprecated with version 3.2.0 (PHP 5.2 requirements)
 * @param object $object
 * @return string unique object hash
 */
function wp_object_hash( &$object ) {
    static $prefix, $count = 0, $property = '__wphookobjhash__', $spl_function_exists;

    isset( $spl_function_exists ) || $spl_function_exists = function_exists( 'spl_object_hash' );

    // prefer spl_object_hash if available
    if ( $spl_function_exists )
        return spl_object_hash( $object );

    // validate input
    if ( !is_object( $object ) ) { 
        trigger_error( __FUNCTION__ . '() expects parameter 1 to be object', E_USER_WARNING );
        return null;
    }
    // setup prefix and counter to generate object hash, set it to object if not set
    isset( $prefix ) || ( ( $prefix = uniqid( '' ) ) && $property .= $prefix . '__' );
    isset( $object->$property ) || ( $object->$property = sprintf( '%s-%08d', $prefix , ++$count ) );
    return $object->$property;
}

Si vous utilisez une version PHP 5, vous n'avez pas besoin de passer le paramètre par référence.

Voici ce que vous voulez.

J'ai corrigé un bug très probable et simplifié la fonction de bobthecow répondre (qui est également emprunté à php. net) à ceci:

if ( !function_exists( 'spl_object_hash' ) ) {
    function spl_object_hash( $object )
    {
        ob_start();
        var_dump( $object );
        preg_match( '[#(\d+)]', ob_get_clean(), $match );
        return $match[1];
    }
}

Elle renvoie un entier (habituellement dans la gamme sub-100), qui est unique pour chaque objet (voir cette réponse pour plus de détails sur ce que vous voyez).


P.S. J'utilise cette mise en œuvre dans un scénario monde réel

uniqid () travail pour votre tâche?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top