L'objet StdClass.

ViPHP
ViPHP | 4674 Messages

25 juil. 2007, 16:22

Bonjour :)

Depuis un moment je me demande qu'est-ce que cet objet bizarre qui porte le nom de StdClass ? Sur la documentation PHP, je n'ai rien trouvé à part :
Le nom stdClass est utilisé en interne par Zend et ne doit pas être utilisé. Vous ne pouvez pas nommer une classe stdClass en PHP.
Pourtant, j'aimerais bien l'utiliser.
Quelles sont les risques ? Et où pourrait-on avoir plus d'informations sur cet objet ?

J'ai juste fais un rapide test pour savoir s'il avait des méthodes, apparement non, ou sinon PHP ne me laisse pas les voir :
foreach(get_class_methods(new stdClass) as $key => $value)
    echo $key . ' ' . $value . "\n";
Pareil pour les propriétés :
foreach(get_class_vars('stdClass') as $key => $value)
    echo $key . ' ' . $value . "\n";
Merci :)
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 928 Messages

25 juil. 2007, 17:14

Std = standard.

Lorsque tu fais dans un code

Code : Tout sélectionner

$foo->bar = 'toto';
ça te créé un objet $foo de type StdClass. En gros c'est la classe passe partout de PHP ;)

ViPHP
ViPHP | 5920 Messages

25 juil. 2007, 17:23

N'empèche HyWaN, ya un seul nom de classe que php interdit, et faut absolument que tu veuilles nommer une classe avec ce nom là précisément... :p

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

25 juil. 2007, 17:46

C'est un peu ce que je me suis dit aussi ... ;)

si tu veux tant que ça une classe standard, utilise standardClass ou stdClasse :?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

25 juil. 2007, 17:47

Je ne connais pas les détails techniques de stdClass, mais je sais que toutes les classes sont des extensions de stdClass par défaut. Quand on utilise
class a {}
...c'est comme si on faisait
class a extends stdClass {}
Ça peut être utile dans la signature d'une fonction
function passez_moi_un_objet(stdClass $obj) {}
Pour le reste... à mon avis t'es pas près de te débarrasser de stdClass donc va falloir songer à un nouveau nom pour ton truc :lol:

Mammouth du PHP | 505 Messages

25 juil. 2007, 17:50

Bah elle est utilisée malgré tout...
si tu fais $obj = (object) $_GET;
$obj devient une stdClass

et dans l'autre sens ca marche aussi.
$tab = (array)$obj; $tab redevient un tableau.

Si tu fais des echanges en json, tu es souvent confronté a la stdClass.

ViPHP
ViPHP | 4674 Messages

25 juil. 2007, 18:09

Quand je disais que je voulais utiliser cette classe, c'était m'en servir, et non pas utiliser le nom lol. Je me suis mal exprimé.

Je ne suis pas encore suffisament bête au point de me borner à un nom de classe ;-) Je peux utiliser un préfixe par exemple (vous voyez, j'ai de l'imagination ;-)).

Donc il n'y a pas de soucis à utiliser cette classe ? On peut l'utiliser dans tous les cas, sans que ça pose un problème quelconque à PHP. Car la doc spécifie que la classe est utilisée en interne par PHP, alors je voulais savoir si ça ne posait pas de problèmes.

Hubert me dit que toutes les classes sont une extension de StdClass. Bien. Seulement, StdClass a des propriétés intéressantes, qu'on ne retrouve pas dans une classe normale. Par exemple :
$a = new stdClass;
$a->b->c = 'hop';
$a->b->e = 'toc';
$a->d = 'la';

echo $a->b->c . ' ' . $a->d . ' ' . $a->b->e . "\n";
print_r($a->b);

foreach($a->b as $key => $value)
    $a->b->$value = $key;

print_r($a->b);
Affiche :

Code : Tout sélectionner

hop la toc stdClass Object ( [c] => hop [e] => toc ) stdClass Object ( [c] => hop [e] => toc [hop] => c [toc] => e )
On ne peut pas avoir un tableau sur $a->b avec une classe normale. Me trompe-je ?

Et si c'est une extension de chaque classe, on ne pourrait plus étendre de classe, car on a le droit qu'à une seule extension (et c'est parfois dommage). Ou alors, c'est fait dans d'autres couches de PHP, sûrement.

Et j'aimerais savoir où on pourrait avoir un peu plus de documentations. Car je compte me servir de cette classe pour un package, et j'aimerais utiliser la stdClass à fond. On peut sûrement faire autre chose que d'assigner des variables :P ?

Merci de m'avoir pris pour un idiot haha :mrgreen:. <- edit : je plaisantais aye :oops: :)
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

ViPHP
ViPHP | 4674 Messages

27 juil. 2007, 15:23

Bien.
J'ai terminé ce que je voulais faire :P
Pour ceux que ça intéresse, voici comment convertir un tableau vers un arbre à objet StdClass.
class MyClass {

    /**
     * convertArrayToObject
     * Convert an array to an StdClass object.
     *
     * @access  public
     * @param   array         array     Array.
     * @param   previousNode  object    Previous node. Do not be set by user.
     * @return  object
     */
    public static function convertArrayToObject ( Array $array, $previousNode = null ) {

        if(null === $previousNode)
            $previousNode = new StdClass;

        foreach($array as $variable => $value) {

            $currentNode = $previousNode;

            if(is_array($value)) {

                $currentNode->$variable = new StdClass;
                self::convertArrayToObject($value, $currentNode->$variable);
            }
            else
                $currentNode->$variable = $value;
        }

        return $currentNode;
    }
}
Voici les tests :
$array = array(
    'database' => array(
        'table' => array(
            'name' => 'testing'
        ),
        'host' => '127.0.0.1'
    ),
    'other' => 'truc'
);

$out = MyClass::convertArrayToObject($array);
print_r($out);

echo $out->database->table->name . "\n" .
     $out->other . "\n";
Affichera :

Code : Tout sélectionner

stdClass Object ( [database] => stdClass Object ( [table] => stdClass Object ( [name] => testing ) [host] => 127.0.0.1 ) [other] => truc ) testing truc
Voilà, bon c'est vraiment tout bête, mais c'était histoire de conclure le sujet ;-)
J'ai utilisé ce système pour utiliser les configurations en .ini.

Par exemple :

Code : Tout sélectionner

database.table.name = testing database.host = 127.0.0.1 other = truc
Me donnerait le tableau ci-dessus. C'est un peu plus compliqué pour construire le tableau. Je ne vais pas poluer le sujet.

Voilà :) Je n'ai pas mis dans « Vos Contributions », car ce n'est pas suffisament compliqué pour être une réelle contribution, c'est juste une idée comme ça :) Libre aux modos de déplacer s'ils en jugent nécessaire ;-)

Ah oui, pour terminer, on peut ajouter un test sur le nom des variables (regex) pour vérifier qu'on aura pas d'erreurs. Je ne l'ai pas mis ici, mais c'est également tout bête car l'expression régulière se trouve dans la documentation :P

Voilà :)
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Mammouth du PHP | 843 Messages

15 déc. 2012, 14:35

Salut Hywan :)
Utilise tu toujours cette methode depuis le temps ?
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

ViPHP
ViPHP | 4674 Messages

15 déc. 2012, 15:50

Euh ça dépend des projets. Parfois il est plus utile de manipuler un tableau, parfois un objet, tout dépend du contexte. Peux-tu préciser un peu ta question ?
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Mammouth du PHP | 843 Messages

15 déc. 2012, 17:05

En fait moi je suis sous zf2 pour le moment et j'aimerai qu'un helper me sorte à la fois des methode et aussi des vars accessible comme un objet et ces vars sont en fait le retour d'un objet stdClass...

un genre d'utilisation:
echo $this->helper()->returnmyobjectstdClass()->index1->var1;
echo $this->helper()->returnmyobjectstdClass()->index1->var2;
echo $this->helper()->returnmyobjectstdClass()->index1->var3->var1;
// ...
Voir même si possible avec les propriété public:
echo $this->helper()->myobjectstdClass->var;
echo $this->helper()->myobjectstdClass->index1->var2;
echo $this->helper()->myobjectstdClass->index1->var3->var1;
// ...
Je ne sait pas si l'on peut faire mieux que l'objet stdClass pour avoir ce genre d'architecture de variable sur plusieurs niveaux ?
Doit t'on etendre stdClass... Doit on definir une fonction convertArrayToObject() comme tu l'a fait...
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

Mammouth du PHP | 843 Messages

15 déc. 2012, 17:58

en fait je suis pris d'un doute depuis la lecture de ceci: http://www.mcherifi.org/developpement-w ... class.html
Cf le commentaire de daminux: "désormais récursif"

Je ne comprend pas ce qu'il entand par là mais je sous entend de ce fait qu'il existe peut être maintenant une autre methode pour arrivé à ce genre de résultat...

Si quelqu'un à une idée sur le sujet ;)
Merci d'avance...
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

ViPHP
ViPHP | 4674 Messages

15 déc. 2012, 18:30

Ton helper te présente les données sous quelle forme actuellement ?
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Mammouth du PHP | 843 Messages

15 déc. 2012, 19:44

Aucune en faite je recherche dejà a voir comment faire pour standardiser mon code à ce niveau :p
Je viens de faire le tour de la question et de comprend qu'il faut voir simplement si besoin en recusivité ou non... En fin de compte c'est toujours mieux en array (voir syntaxe encore plus light qu'un array en php niveau perf) que recurcivement je pense. Mais si tu doit compilé du php par exemple. Le travail sur chaine classique d'utilisation de propriété "tableau" dans tes classes demandera un echappement massif des ' de chaque index de tableau qui peut être contourner par les syntaxes objet.

On doit sans doute aussi garder l'oeil sur un rapport factorisation de code / performance je suppose...

Enfin c'est mon avis sur le pourquoi utilise t'on des stdClass et autre ArrayObject mais est ce que j'ai bien tout compris??? :p
Si quelqu'un ce sent pour une théorie sur le sujet :D

En gros est il plus performant de faire, au sein d'une classe, l'instanciation d'une classe de definition de variable, ou, par la création/definition d'une propriété etant un array ?
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

ViPHP
ViPHP | 4674 Messages

16 déc. 2012, 19:12

Les tableaux en PHP sont des hashmaps. Les objets sont des instances de classes. Une classe est une zone mémoire à laquelle sont rattachés des méthodes qui travaillent sur des données qui appartiennent elles-mêmes à différentes zones mémoires (statique ou dynamique).

Si tu connais un peu le C, une classe est strictement équivalente à une structure. Un bête record qui permet d'associer des données à des symboles (noms). En PHP, on a la classe StdClass qui permettrait d'en faire autant, mais l'habitude est plutôt d'utiliser les tableaux pour ça. L'impact mémoire est différent, tout comme la vitesse d'exécution. Il faut prendre ça en considération lorsque l'on manipule des millions de données, car c'est uniquement dans ce cas que l'on verra une différence (faire $array['foo'] ou $object->foo est différent, car 'foo' est une chaîne qui va être transformée en hash pour trouver la valeur associée — notons que les chaînes sont représentées par des buffers en C —, alors que foo dans $object->foo est un symbole, donc il faut parcourir la table des symboles). Mais (!), PHP n'est pas conçu pour traiter des millions de données, son exécution est linéaire (contrairement à d'autres machines virtuelles qui utilisent des astuces, comme JIT, pour accélérer les codes exécutés plusieurs fois).
Bref, utilises les tableaux, c'est franchement plus simple dans ton cas et StdClass n'apportera rien de plus.

Cette StdClass a été créée comme fallback pour plusieurs fonctions PHP. Par exemple une lecture de base de données pour produire un tableau ou un objet. Les propriétés ne sont pas les mêmes : un tableau est très souvent copié lors d'un passage en argument d'une fonction, alors que pour un objet, c'est toujours sa référence qui est passée, donc on ne copie pas l'objet mais sa référence. Ça peut-être intéressant.

Tu parles aussi de ArrayObject. C'est une classe proposée par la SPL. C'est une classe qui se comporte comme un tableau grâce aux interfaces ArrayAccess, Countable etc. Sauf que l'objectif n'est pas de stocker de bêtes chaînes ou entiers mais des tableaux, et en grande quantité. (Note : si on veut un itérateur sur un tableau, il est préférable d'utiliser ArrayIterator plutôt que ArrayObject).

Donc, pour reprendre mon bref : utilise les tableaux et ça ira tout bien. Réfléchis juste à ce que tu vas mettre dedans et comment tu vas l'agencer, ça fera tout le boulot niveau optimisation.

Ah oui, tu parlais de transformer les clés, d'échapper les guillemets simples, les espaces etc. Sache que tu peux écrires : $object->{"abc'def ghi"}, et ça fonctionnera tout bien.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).