mageekblog - Mot-clé - arrayAccess - CommentairesLe blog personnel de Frédéric Hardy. Au menu, PHP, agilité, FreeBSD, cuisine et photographies.2021-12-02T08:20:54+01:00Frédéric Hardyurn:md5:26874ca5b8cd4cac8d08b0e68e64f63aDotclearÀ propos de l'interface \arrayAccess et des fonctions array_* - Blanchon Vincenturn:md5:1d5bd27eaa3e2b92d74d6c23a1b4878f2013-02-26T14:05:48+01:002013-02-27T10:47:59+01:00Blanchon Vincent<p>Comme le dit @francoism et @mageekguy, "Interface to provide accessing objects as arrays." et frederic, c'est accéder à un objet comme un tableau. Le mot "accéder" est pourtant pas compliqué. A aucun moment la doc affirme que c'est un tableau.</p>
<p>@Eric "l'interface permet d'accéder aux objets comme s'ils étaient des tableaux", enlève le "comme s'ils étaient des tableaux" et remplace par "comme des tableaux", tu comprendras mieux avec une meilleure traduction, la doc dit pas que c'est objets sont comme des tableaux, mais juste l'accès peut se faire comme un tableau, c'est différent <img src="/themes/default/smilies/wink.png" alt=";)" class="smiley" /></p>À propos de l'interface \arrayAccess et des fonctions array_* - francoismurn:md5:477325fb66c6cd94648350c21fe3986c2013-02-26T08:47:32+01:002013-02-26T09:37:13+01:00francoism<p>Ca semble pourtant évident: il ne faut pas confondre “accéder” et “manipuler”.<br />
“Accéder” permet de lire/écrire une valeur à un offset donné, ce que définit l'interface.<br />
“Manipuler“ donnerait la possibilité de réorganiser l'ensemble des clés/valeurs, et ça ce n'est clairement pas le rôle d'une interface et cela ne garantit en aucun cas la compatibilité avec quoi que ce soit.<br />
De plus la documentation des fonctions array_* spécifie systématiquement un paramètre de type array et non un objet et indique même parfois le caractère exclusif de ce comportement depuis PHP5 (cf la doc d'array_merge <a href="http://www.php.net/manual/en/function.array-merge.php" title="http://www.php.net/manual/en/function.array-merge.php" rel="nofollow">http://www.php.net/manual/en/functi...</a> par exemple.</p>À propos de l'interface \arrayAccess et des fonctions array_* - Guileurn:md5:3b6f32412f57e46fbf2e59361f3112c02013-02-24T23:31:40+01:002013-02-26T09:36:45+01:00Guile<p>Je vais continuer dans la mauvaise foi moi :<br />
"Si tu *push(), tu t'attends à ce que ça arrive à la fin."<br />
> Faux. Push envoie en haut de la pile (stack). Pop retire le haut de la pile.<br />
Si l'implémentation de pile par défaut en php fait est un tableau dont le haut est à la fin, ce n'est pas la seule solution envisageable...</p>
<p>Bon, sinon ce serait bien que PHP s'amuse à rendre un vrai objet "Array" non?</p>À propos de l'interface \arrayAccess et des fonctions array_* - Adrienurn:md5:9df9f821a75097edd39a461c909b9a5e2013-02-22T20:54:45+01:002013-02-22T22:23:12+01:00Adrien<p>J'ajoute que ArrayAccess sans Traversable ne donne pas accès à la liste des clés (ni celle des valeurs) et donc qu'une bonne partie des fonctions array_* n'a aucun sens sur de tels objets.</p>À propos de l'interface \arrayAccess et des fonctions array_* - Rezouceurn:md5:179cbdabba0a509dec4cded4057b501d2013-02-22T14:51:54+01:002013-02-23T10:16:09+01:00Rezouce<p>La doc de array_push dit aussi :</p>
<blockquote><p>Has the same effect as <code>$array[] = $var;</code></p>
</blockquote>
<p>Mais autant un array_push, ce n'est pas trop gênant puisque justement on peut faire (plus) facilement ce qu'on veut autrement, autant d'autres fonctions comme array_merge, array_filter, array_map, etc., on aimerait parfois pouvoir les utiliser sur des objets avec une interface d'array.<br />
Si pour que ça plaise au plus grand nombre, il faille une interface plus restrictive que ArrayAccess, pourquoi pas. Mais ce serait bien de l'avoir.</p>À propos de l'interface \arrayAccess et des fonctions array_* - mageekguyurn:md5:2cea4849dd645edb2619f33a6b09efe82013-02-22T14:47:30+01:002013-02-22T15:13:53+01:00mageekguy<p>@<a href="http://blog.mageekbox.net/?post/a-propos-de-interface-arrayAccess-et-des-fonctions-array#c4787" rel="nofollow">PKoin</a> : Si tu <code>*push()</code>, tu t'attends à ce que ça arrive à la fin.</p>
<p>C'est même que c'est nécessaire au bon fonctionnement de ton algorithme (tri ou tout ce que tu veux).</p>
<p>Donc se baser sur quelque chose qui ne te donne pas la garantie que l'élément que tu ajoutes sera effectivement ajoutée à la fin est plus que dangereux, c'est totalement stupide puisque cela risque d'introduire un bug dans ton code en fonction du type d'objet que tu manipules et de l'implémentation de <code>arrayAccess::offsetSet()</code> sous-jacente.</p>
<p>Donc même si c'était faisable techniquement au niveau du Zend Engine, ça serait une idiotie totale de le permettre, à moins de mettre des contraintes plus fortes sur <code>\arrayAccess</code> (mais avec la base de code existante, j'ai comme un doute que ça soit faisable) ou d'imposer par exemple qu'un objet utilisable avec <code>array_push()</code> soit une pile, à l'aide d'une interface <code>\stack</code>.</p>
<p>Bref, <code>$object[] = 'foo'</code> n'est pas forcément équivalent à <code>$array[] = 'foo'</code> et ne peut donc en conséquence pas être utilisé par <code>array_push()</code> et de toute façon <code>\arrayAccess</code> n'est pas conçue pour faire passer un objet pour un tableau aux yeux du Zend Engine, comme l'a très bien dit Julien.</p>
<p>Et oui, c'est regrettable, mais j'ai envie de dire que si tu as besoin de généraliser une méthode de manipulation de données, soit tu utilises partout et tout le temps des tableaux en faisant manuellement la conversion objet vers tableau aux endroits idoines, soit tu utilises partout et tout le temps des objets et tu leur impose une interface commune afin d'avoir un traitement générique qui prend de manière transparente en charge les conversions nécessaires.
</p>
<p>Pour devoir faire avec la première solution, c'est dangereux car c'est de la responsabilité du développeur de ne pas oublier de faire les conversions nécessaires explicitement (et le développeur est faillible par nature), et je te recommandes donc la seconde solution qui a fait ses preuves depuis longtemps.</p>
<p>Après tout, c'est à cela que sert la POO en général et les interfaces en particulier.</p>À propos de l'interface \arrayAccess et des fonctions array_* - PKoinurn:md5:41fe3fabceed4a5edef552d1db9625dc2013-02-22T14:45:32+01:002013-02-22T14:47:09+01:00PKoin<p>Pour moi tout est question de philosophie sur les interfaces.<br />
Si tu me mets à disposition une interface, libre à moi de gérer son implémentation en conservant de la cohérence.<br />
Si concrètement je décide de pusher un élément dans mon objet qui implémente l'interface ArrayAccess, libre à moi de le faire au début ou à la fin. Peu importe.<br />
Dans ton exemple, tu joues sur les termes de la description de array_push : "onto the end of array". Si j'ai fait le choix dans l'implémentation d'offsetSet() que le set se fasse en début. Alors, c'est aberrant que le array_push me soit interdit car c'est une fonction qui ajoute un élément en FIN de tableau. Si je considère que pour moi la "fin" de mon objet correspond au début d'une de ses variables (ça parait débile, certes), le langage n'a pas d'intérêt de bloquer cela.</p>
<p>La réponse de @julienPauli : <a href="https://twitter.com/julienPauli/status/304920496921792512" title="https://twitter.com/julienPauli/status/304920496921792512" rel="nofollow">https://twitter.com/julienPauli/sta...</a> ça par contre je peux l'entendre.</p>À propos de l'interface \arrayAccess et des fonctions array_* - Ericurn:md5:655a03a006440056e33b4e49540589a32013-02-22T14:28:35+01:002013-02-22T14:33:42+01:00Eric<p>> Interface to provide accessing objects as arrays.</p>
<p>> Il est donc très clair à mes yeux que le but de cette interface n’est pas de permettre<br />
> de faire passer un objet pour un tableau, mais juste de permettre l’utilisation de<br />
> l’opérateur <a href="http://blog.mageekbox.net/?post/" rel="nofollow"></a> sur un objet puisqu’il est l’interface privilégiée pour modifier le contenu<br />
> d’un tableau ou y accéder.</p>
<p>Autant je peux comprendre l'argument de fond, autant là tu es de mauvaise foi. Il est au contraire très clair que "l'interface permet d'accéder aux objets comme s'ils étaient des tableaux". C'est la traduction pure et simple. La phrase ne parle pas de crochets. C'est peut être comme ça que c'est implémenté, mais ce n'est pas ça qui est dit, du tout.</p>
<p>Pour moi il y a l'interface publique et le fonctionnement interne. Tu ne sais pas ce que veut dire ajouter un élément à la fin d'un objet ? Tu n'as pas à le savoir. Tu as à savoir que l'objet sait répondre à un certain appel et que cet appel est décrit comme représentant une fonctionnalité précise. Après l'objet fait ce qu'il veut en interne, c'est le principe même de toute la POO.</p>
<p>Après il s'agit de ménager l'historique en faisant évoluer le langage. Mixer des types simples avec des objets c'est toujours une galère conceptuelle, dans tous les langages. L'idée des interfaces ArrayAccess et autres c'est aussi de permettre des transitions douces, pas que de reproduire une syntaxe.</p>
<p>Qu'il pourrait être pertinent d'avoir une interface supplémentaire, par exemple un ArrayStack qui sait recevoir les push/pop/(un)shift, pourquoi pas. C'est peut être le seul argument soulevé qui raisonne bien chez moi. Disons que pour les tableaux <a href="http://blog.mageekbox.net/?post/" rel="nofollow"></a> et array_push sont équivalents et que l'interface est faite pour fonctionner comme les tableaux, donc ça m'aurait semblé logique de l'implémenter de la même façon.</p>
<p>D'ailleurs si on s'en tenait à tes arguments, ArrayObject devrait accepter le array_push étant donné que là c'est très explicitement de recréer le fonctionnement d'un tableau. Je crois que c'est en partie plus une question de "on n'a pas modifié les fonctions historiques", soit parce que c'est du boulot, soit parce que ça peut avoir des impacts de perf ou de compatibilité. Bref, une question beaucoup plus technique. J'ai l'impression que tu justifies après coup une question technique par des arguments philosophiques qui n'en sont pas du tout l'origine, et que l'argument principal est "parce que ça ne fonctionne pas comme ça" (et là nous sommes d'accord, c'est bien ce qu'on discute).</p>À propos de l'interface \arrayAccess et des fonctions array_* - Julien Breuxurn:md5:ae0df863a2d9a8be12c28b29174f7dc62013-02-22T14:26:14+01:002013-02-22T14:33:42+01:00Julien Breux<p>Eventuellement peut-être un problème de vocabulaire avec ce "faux ami/type" : "array" ?</p>
<p>Bref :<br />
object extends \arrayAccess !== (array)object</p>