spl_object_hash para PHP < 5.2 (IDENTIFICADOR único para las instancias de objeto)

StackOverflow https://stackoverflow.com/questions/2299463

  •  21-09-2019
  •  | 
  •  

Pregunta

Estoy tratando de conseguir la Id de instancias de objetos en PHP 5+.

La función, spl_object_hash() está disponible a partir de PHP 5.2, pero me pregunto si hay una solución para las anteriores versiones de PHP.

Hay un par de funciones en los comentarios sobre php.net pero no trabajan para mí.La primera (simplificado):

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

no funciona con objetos nativos (como DOMDocument), y el segundo:

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

parece que podría ser un gran rendimiento buster!

¿Alguien tiene algo bajo la manga?

¿Fue útil?

Solución

Me corrió un par de pruebas rápidas. Realmente creo que sería mejor que el almacenamiento de las devoluciones de llamada reales en su función bind () usando bind('evt_name', array($obj, 'callback_function')). Si a pesar de todo quiere ir a la ruta spl_object_hash, en lugar de almacenar referencias con los enlaces de eventos, que está viendo algo como esto:

Un var_dump / extracto y ID de hash aplicación:

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

Una implementación ingenua referencias:

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

Éste era básicamente 5-50x peor que la función de referencia basado en clases en todos los ámbitos, así que no es un valor aproximado de preocupante.

Un almacenar referencias de implementación de la clase:

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

Y se termina con resultados que se ven así . Resumen: las referencias de aplicación lleva a cabo a base de clases mejores de la zona n / 50 clases - en su mejor momento, se las arregla para sacar 1/3 el rendimiento de la aplicación basada var_dump, y por lo general es más peor <. / p>

La aplicación var_dump parece ser tolerable, aunque no es lo ideal. Pero si usted no está haciendo demasiadas de estas búsquedas, no va a ser un cuello de botella para usted. Especialmente como un mensaje para PHP <5,2 BOXEN.

Otros consejos

Me escribió una vez una función de ayuda para WordPress que ofrece un control único, por objeto, funciona con un contador y almacena el hash por una propiedad de clase pública si se ha asignado a un objeto. El siguiente ejemplo demuestra esto:

/**
 * 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 está utilizando una versión de PHP 5, que no es necesario pasar el parámetro por referencia.

Esto es lo que quieres.

He corregido un muy probable error y racionalización de la función de bobthecow respuesta (que es también tomado de la php.net a este:

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

Devuelve un entero (por lo general en la sub-rango de 100), que es único para cualquier objeto (ver esta respuesta para más detalles sobre lo que estamos viendo).


P. S.Yo uso esta aplicación en un escenario real aquí

uniqid () trabajo para su tarea?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top