POO - PARAMETERHOLDER CLASS

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 8 janv. 2010 à 13:15
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 13 janv. 2010 à 10:35
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/51093-poo-parameterholder-class

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
13 janv. 2010 à 10:35
Pas de quoi pour le coup de pouce ^^
Pour l'erreur à la con sur offsetSet(), j'ai une excuse monsieur le juge, j'étais debout depuis minuit et demi, j'étais donc en fin de journée, prêt à me coucher... Bon, je suppose que tu as réussi à la déboguer tout seul ;)
Waredan Messages postés 22 Date d'inscription vendredi 8 janvier 2010 Statut Membre Dernière intervention 19 février 2010
13 janv. 2010 à 10:00
Okay, il est vrai que remplacer tout les tableaux par une instance de "ParameterHolder" dès l'instanciation si l'on passe un tableau multidimensionnel peut s'avérer lourd. Un mixte des deux, on change un tableau par une instance de "ParameterHolder" uniquement lorsqu'on tente de y accéder, puis on le réaffecte à l'index spécifié pour une utilisation future. Enfin, toutes nouvelles valeurs passées sous forme de tableau sont également remplacées par une instance de "ParameterHolder", sinon, le chainage "$parameterHolder['first_section']['one']" fonctionne, mais pas celui-çi "$parameterHolder->second_section->path". Merci pour le coup de pouce ;)

NB : ArrayObject::offsetSet() expects exactly 2 parameters, 1 given ;)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
12 janv. 2010 à 18:12
Voui, le résultat est le même.
Sauf que ta manière de définir les "propriétés" dans le constructeur ne me plaît qu'à moitié : dans l'idée, elle dispense de surcharger offsetGet(), mais... je trouve ça lourd. Alors que si tu te contentes de passer le tableau du constructeur au constructeur parent (celui de ArrayObject donc) alors tu peux retourner des instances de ArrayObject instanciées à la volée. Eventuellement, tu peux remplacer les tableaux de dimension > 1 par une instance de ArrayObject, manière de faire un "semblant de cache" (pour ne pas réinstancier 30 fois un ArrayObject si on tente d'accéder plusieurs fois à une propriété tableau. Je suis pas certain d'être clair... Je vais tenter un bout de code.

public function offsetGet($offset) {
$return = parent::offsetGet($offset);
if (is_array($return)) {
$return = new static($return);
$this -> offsetSet($return);
}
return $return;
}

Ca revient au même que de le faire dans le constructeur, sauf que comme ça, on ne le fait que pour les propriétés auxquelles on accède.
Après, c'est juste une question de goût ^^
Waredan Messages postés 22 Date d'inscription vendredi 8 janvier 2010 Statut Membre Dernière intervention 19 février 2010
12 janv. 2010 à 17:05
Je suis d'accord avec toi, on peut redéfinir la méthode "offsetGet" afin qu'elle retourne une instance "ArrayObject" si la valeur est un tableau, ce qui permet bien le chaînage "$params['first_section']['one']" ou "$params->second_section->path" MAIS UNIQUEMENT si l'on a déjà passé ces paramètres sous forme de tableau au constructeur.

Hors, je souhaitais pouvoir garder la possibilité de définir des paramètres non-définies lors de l'instanciation de la classe, tout en ayant cette possibilité de chainage.

Pour cela, c'est la méthode "offsetSet" qui doit être redéfinie, ainsi que le constructeur, cf. modification de la source.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
12 janv. 2010 à 11:52
Ah ! Je me disais aussi ^^

Pour mes besoins perso, j'ai utilisé également ArrayObject avec le flag ArrayObject::ARRAY_AS_PROPS. Par contre, j'ai surchargé la méthode offsetGet pour que si l'élément est un tableau, il renvoit une instance d'ArrayObject, avec le même flag.
Par contre, je charge dans l'instance directement un tableau lu dans un fichier de config, parce qu'en réalité, ça n'a pas beaucoup de sens de définir des variables dans le script qui charge la config...
Waredan Messages postés 22 Date d'inscription vendredi 8 janvier 2010 Statut Membre Dernière intervention 19 février 2010
12 janv. 2010 à 11:41
À vrai dire, je ne devais pas tout à fait être réveillé ..

$params = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);

$params['first_section'] = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$params['first_section']['one'] = 1;
$params['first_section']['two'] = 2;

$params->second_section = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$params->second_section->path = '/path/to/something';
$params->second_section->url = 'http://php.net/';

echo $params->first_section->one; // 1

echo $params['second_section']['path']; // '/path/to/something';

var_dump(isset($params->second_section->path)); // bool(true)

unset($params->second_section->path);

var_dump(isset($params->second_section->path)); // bool(false)

print_r($params);

//ArrayObject Object
//(
// [storage:ArrayObject:private] => Array
// (
// [first_section] => ArrayObject Object
// (
// [storage:ArrayObject:private] => Array
// (
// [one] => 1
// [two] => 2
// )
// )
//
// [second_section] => ArrayObject Object
// (
// [storage:ArrayObject:private] => Array
// (
// [url] => http://php.net/
// )
// )
// )
//)

C'est la même chose, ça prends moins de place :$
Pyrrah Messages postés 127 Date d'inscription mercredi 16 février 2005 Statut Membre Dernière intervention 15 février 2010 4
8 janv. 2010 à 13:47
Hum, désolé moi non plus :/
Serait-il possible d'avoir des explications supplémentaires ? :)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
8 janv. 2010 à 13:15
Salut,

Je ne comprends pas bien l'intérêt de cette classe... Pourquoi ne pas simplement étendre ArrayObject ?
Désolé, vraiment, je ne comprends pas l'utilité...
Rejoignez-nous