Domanda

Sto cercando di ottenere un unico Id per le istanze di oggetti in PHP 5+.

La funzione, spl_object_hash() è disponibile da PHP 5.2, ma mi chiedo se c'è una soluzione per le vecchie versioni di PHP.

Ci sono un paio di funzioni di commenti php.net ma non sta lavorando per me.Il primo (semplificato):

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

non funziona con gli oggetti nativi, come DOMDocument), e la seconda:

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

sembra che potrebbe essere una delle principali prestazioni buster!

Qualcuno ha qualcosa nella manica?

È stato utile?

Soluzione

Ho eseguito un paio di test rapidi. Credo davvero che si sarebbe meglio memorizzare i callback reali nella vostra funzione bind () utilizzando bind('evt_name', array($obj, 'callback_function')). Se si vuole assolutamente andare via spl_object_hash, invece di memorizzare i riferimenti con i binding di eventi, si sta guardando qualcosa di simile:

Un'implementazione var_dump / estratto e 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;
}

Un'implementazione riferimenti ingenui:

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

Questa è stata fondamentalmente 5-50x peggiore della funzione di riferimento di classe a base di tutta la linea, quindi non vale la pena preoccuparsi.

un negozio di riferimenti di implementazione della 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;
}

E si finisce con risultati che assomigliano a questo . Sommario: l'attuazione riferimenti basato classe esegue migliore in circolazione n / 50 classi - al suo meglio, riesce a tirare fuori 1/3 le prestazioni della realizzazione var_dump based, e di solito è molto peggio <. / p>

L'implementazione var_dump sembra essere tollerabile, anche se non è l'ideale. Ma se non stai facendo troppi di questi ricerche, non sarà un collo di bottiglia per voi. Soprattutto come ripiego per PHP <5.2 boxen.

Altri suggerimenti

Una volta ho scritto una funzione di supporto per wordpress che offre un hash univoco per ogni oggetto, funziona con un contatore e memorizza il valore hash per come struttura di classe pubblico se è stato assegnato ad un oggetto. L'esempio seguente dimostra questo:

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

Se si utilizza una versione di PHP 5, non è necessario passare il parametro per riferimento.

Questo è ciò che si desidera.

Ho risolto molto probabile bug e ottimizzato la funzione da bobthecow risposta (che è anche preso in prestito da php.net) a questo:

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

Restituisce un numero intero (di solito nel sub-100), che è unico per ogni oggetto (vedere questa risposta per maggiori dettagli su quello che si sta vedendo).


P. S.Io uso questa implementazione in uno scenario reale qui

uniqid () lavoro per il vostro compito?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top