Frage

Ich versuche eindeutige IDs für Objektinstanzen in PHP 5+ zu erhalten.

Die Funktion, spl_object_hash() ist bei PHP 5.2 erhältlich, aber ich frage mich, ob es eine Problemumgehung für ältere PHP -Versionen gibt.

In den Kommentaren zu Php.net gibt es einige Funktionen, aber sie arbeiten nicht für mich. Das erste (vereinfacht):

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

Funktioniert nicht mit nativen Objekten (wie Domdocument) und der zweiten:

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

Sieht so aus, als könnte es ein großer Leistungsbuster sein!

Hat jemand etwas im Ärmel?

War es hilfreich?

Lösung

Ich habe ein paar schnelle Tests durchgeführt. Ich denke wirklich, dass Sie besser dran sind, echte Rückrufe in Ihrer Bind () -Funktion zu speichern bind('evt_name', array($obj, 'callback_function')). Wenn Sie unbedingt die Route spl_object_hash gehen möchten, anstatt Referenzen mit den Ereignisbindungen zu speichern, sehen Sie sich so etwas an:

Eine Var_dump / Extrakt- und Hash -ID -Implementierung:

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

Eine naive Referenz -Implementierung:

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

Dieser war im Grunde genommen 5-50x schlechter als die klassenbasierte Referenzfunktion auf der ganzen Linie, daher lohnt es sich nicht, sich Sorgen zu machen.

Ein Geschäft referenziert nach Klassenimplementierung:

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

Und du hast am Ende mit Ergebnisse, die so aussehen. Zusammenfassung: Die Implementierung der klassenbasierten Referenzen führt am besten in den Klassen von N/50 aus-am besten schafft sie 1/3 die Leistung des var_dump basierte Implementierung, und es ist normalerweise viel schlechter.

Das var_dump Die Implementierung scheint erträglich zu sein, wenn auch nicht ideal. Aber wenn Sie nicht zu viele dieser Lookups durchführen, ist dies kein Engpass für Sie. Vor allem als Fallback für PHP <5.2 -Köpfen.

Andere Tipps

Ich habe einmal eine Helferfunktion für WordPress geschrieben, die einen einzigartigen Hash pro Objekt anbietet. Er arbeitet mit einem Zähler und speichert den Hash pro als öffentliche Klasseneigenschaft, wenn er einem Objekt zugewiesen wurde. Das folgende Beispiel zeigt dies:

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

Wenn Sie eine PHP 5 -Version verwenden, müssen Sie den Parameter nicht per Referenz übergeben.

Das ist, was du willst.

Ich habe einen sehr wahrscheinlichen Fehler behoben und die Funktion von der Funktion gestoppt BOBTHECOW ANTWORT (Das wird auch von Php.net ausgeliehen) zu diesem:

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

Es gibt eine Ganzzahl zurück (normalerweise im Sub-100-Bereich), was für jedes Objekt einzigartig ist (siehe Diese Antwort für Details zu dem, was Sie sehen).


PS Ich verwende diese Implementierung in einem realen Szenario hier

Möchten Uniqid () für Ihre Aufgabe arbeiten?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top