53 votes

Comment trouver l'ID d'un objet en PHP ?

J'utilise PHP 5.2. J'aimerais trouver un moyen d'obtenir un identifiant unique pour chaque objet, afin qu'il soit facile de voir quels objets sont les mêmes lorsque l'on consulte les journaux.

En Ruby, je dirais simplement object.object_id pour obtenir l'identifiant interne de Ruby pour l'objet. Il ne semble pas y avoir de moyen évident de faire cela en PHP.

Existe-t-il un moyen intégré de faire cela ? Si ce n'est pas le cas, avez-vous d'autres suggestions ?

86voto

azkotoki Points 1681

Utilisez spl_object_hash() pour ça.

Il renvoie un identifiant unique pour chaque instance d'objet, et non le nom de la classe, il semble donc plus adapté pour vous.

Edit :

Pour les utilisateurs de PHP < 5.2.x, voir cette réponse .

3 votes

Si les objets sont égaux, c'est-à-dire qu'ils ne diffèrent que par leur identité, les hachages d'objets sont produits par spl_object_hash() peuvent sembler très similaires. Je viens d'essayer et j'ai obtenu ceci : a : 00000000462ff471000000005e39f75b b : 00000000462ff46c000000005e39f75b Ils sont différents mais il faut regarder attentivement.

2 votes

Notez également le commentaire de planetbeing sur la page de la référence concernant la possibilité que les hashs soient les mêmes lorsque la référence est détruite.

0 votes

@Ollie Saunders, Pour corriger cela, vous pouvez prendre le hachage (par exemple SHA1) de l'adresse de l'utilisateur. sql_object_hash() . Cependant, il y a pourrait des collisions, mais je ne pense pas qu'il faille s'en inquiéter dans ce cas.

17voto

mindplay.dk Points 2555

Il n'y a actuellement aucun moyen de faire cela en PHP, à partir de la version 5.3.6.

spl_object_hash() ne fait pas ce que vous voulez - parce qu'il recycle les identifiants lorsque les objets sont supprimés, cela conduira à des erreurs dans (par exemple) un mappeur objet-relationnel essayant de garder la trace des objets dans une session.

La description en haut de la page de documentation ("Cette fonction renvoie un identifiant unique pour l'objet. Cet identifiant peut être utilisé comme une clé de hachage pour le stockage des objets ou pour l'identification d'un objet.") est erronée - la vérité est révélée dans la note de cette page : "Lorsqu'un objet est détruit, son hash peut être réutilisé pour d'autres objets", ou en d'autres termes, la fonction ne fait pas pas renvoient toujours un identifiant unique, et peuvent pas toujours être utilisé pour stocker ou identifier des objets.

La technique démontrée dans ce commentaire peut fonctionner dans certains cas, mais elle n'est pas fiable et ne fonctionnera pas non plus de manière cohérente, puisque toute tentative d'accès à une propriété non définie invoquera les méthodes magiques __get() et __set(), dont les résultats sont imprévisibles.

En conclusion, la réponse courte à votre question (malheureusement) est "non" - il n'y a pas de méthode de ce type en PHP, et il n'y a aucun moyen d'écrire une méthode comme celle-ci qui fonctionnera de manière cohérente pour n'importe quel objet.

Si vous souhaitez que cette fonctionnalité soit ajoutée à PHP, veuillez voter et/ou commenter ici :

http://bugs.php.net/bug.php?id=52657

0 votes

La technique alternative fonctionnera tant que l'objet donné n'implémente pas l'option __get , __set y __isset des méthodes magiques. Vous avez raison de dire que (par exemple) un mappeur objet-relationnel peut utiliser celles-ci, pour mapper des propriétés indéfinies sur des colonnes de table. Des choses bizarres peuvent se produire à ce stade lorsque l'ORM essaie de gérer les __oid__ propriété.

0 votes

Je crois que vous ne faites que répéter ce que j'ai déjà dit sur les méthodes magiques ? Et la plupart des ORM modernes utilisent ClassReflection::getProperties(), donc ils ne verront pas la méthode oid propriété. Si votre ORM n'utilise pas vraiment tout La plupart des ORM utilisent une configuration de mappage, des conventions, des méta-données intégrées ou des tables de réflexion, ou des combinaisons de ces éléments...

0 votes

Non, je ne faisais qu'expliquer mieux ce que vous avez dit sur les méthodes magiques, qui n'était pas correct à 100%. Tu as manqué __isset :)

9voto

i336_ Points 665

⚠️ Introduction de PHP 7.2.0 spl_object_id() !

$test = (object)[];
var_dump(spl_object_id($test)); # int(1)

Caveat emptor( ?) :

Lorsqu'un objet est détruit, son identifiant peut être réutilisé pour d'autres objets.

1voto

rolacja Points 2264

Je sais que c'est un vieux sujet, mais je pense avoir trouvé une solution.

L'astuce consiste à stocker la référence à chaque objet dans un tableau avec une clé assignée. Vous pouvez alors obtenir l'identifiant de l'objet en cherchant dans ce tableau et en retournant la clé trouvée.

<?php

class objectMarker
{
    private $storage;

    function add($object) {
        $this->storage[] = $object;
    }

    function getId($object) {
        foreach ($this->storage as $id => $item) {
            if ($item === $object) {
                return $id;
            }
        }

        return null;
    }
}

$marker = new objectMarker;

$t1 = new stdClass;
$t2 = new stdClass;

$marker->add($t1);
$marker->add($t2);

echo $marker->getId($t1) . "\n";
echo $marker->getId($t2) . "\n";

unset($t1);

$t1 = new stdClass;
$marker->add($t1);

echo $marker->getId($t1) . "\n";

$t2->x = 1;
echo $marker->getId($t2) . "\n";

/* output:
0
1
2
1
*/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X