Pourquoi renvoyer un objet au lieu d'un tableau?

84

Je travaille beaucoup sur WordPress et j'ai remarqué que beaucoup plus de fonctions retournent des objets que des tableaux. Les résultats de la base de données sont renvoyés sous forme d'objets, sauf si vous demandez spécifiquement un tableau. Les erreurs sont renvoyées sous forme d'objets. En dehors de WordPress, la plupart des API vous donnent un objet au lieu d'un tableau.

Ma question est la suivante: pourquoi utilisent-ils des objets au lieu de tableaux? Pour la plupart, cela n'a pas trop d'importance, mais dans certains cas, je trouve que les objets sont plus difficiles non seulement à traiter, mais à envelopper ma tête. Y a-t-il une raison de performance à utiliser un objet?

Je suis un programmeur PHP autodidacte. J'ai un diplôme d'arts libéraux. Alors pardonnez-moi si je manque un aspect fondamental de l'informatique. ;)

Dennis
la source
5
Je suis curieux à ce sujet en ce qui concerne les inconvénients des objets, comme ne pas pouvoir utiliser count()ou array_*()fonctionner sur eux (au moins en ce qui concerne le stockage / le retour des données key => value). Personne ne semble le mentionner, ou est-ce que je manque quelque chose?
Wesley Murch
8
Les objets peuvent être rendus dénombrables et itérables en implémentant des interfaces Countable ou Iterator. Consultez également php.net/manual/en/book.spl.php .
simshaun
Si SPL est installé et que vous implémentez l'interface countable pour votre classe d'objet, vous pouvez appeler count()un objet.
Personne ne quitte le SE le
2
Dans de nombreux cas, un tableau n'a même pas de sens car vous ne renvoyez pas une collection d'objets ou un type de collection qui n'est pas facilement émulé avec des tableaux. Lorsque vous avez juste une séquence d'autres valeurs et aucune sémantique supplémentaire associée, alors pour l'amour de Dieu, retournez un tableau - mais vous constaterez que c'est rarement le cas.
8
@delnan et autres: Veuillez noter que @Dennis parle de tableaux associatifs , (alias. Dictionaries, alias. Maps), pas de tableaux normaux (index entier). Ce sont une fonctionnalité fondamentale de PHP et servent plus ou moins le même objectif que les classes dynamiques ( stdClass). Je ne suis pas sûr que cette question ait une réponse autre que "Parce que les programmeurs qui travaillent principalement en POO préfèrent la sémantique de l'utilisation des objets"
BlueRaja - Danny Pflughoeft

Réponses:

62

Voici les raisons pour lesquelles je préfère les objets en général:

  • Les objets contiennent non seulement des données mais aussi des fonctionnalités.
  • Les objets ont (dans la plupart des cas) une structure prédéfinie. Ceci est très utile pour la conception d'API. En outre, vous pouvez définir les propriétés comme publiques, protégées ou privées.
  • les objets s'adaptent mieux au développement orienté objet.
  • Dans la plupart des IDE, l'auto-complétion ne fonctionne que pour les objets.

Voici quelque chose à lire:

Galère Sascha
la source
3
le premier lien ne semble pas bon? Je veux dire que cela fonctionne, mais prend un autre aritcle
Geo
24

Ce n'est probablement pas quelque chose que vous comprendrez profondément jusqu'à ce que vous ayez travaillé sur un grand projet logiciel pendant plusieurs années. Beaucoup de nouveaux majors en informatique vous donneront une réponse avec tous les bons mots (encapsulation, fonctionnalité avec des données et maintenabilité) mais peu comprendront vraiment pourquoi tout cela est bon d'avoir.

Passons en revue quelques exemples.

  • Si des tableaux ont été renvoyés, alors soit toutes les valeurs doivent être calculées à l'avance, soit beaucoup de petites valeurs doivent être renvoyées avec lesquelles vous pouvez créer les valeurs les plus complexes.

Pensez à une méthode API qui renvoie une liste d'articles WordPress. Ces articles ont tous des auteurs, les auteurs ont des noms, une adresse e-mail, peut-être même des profils avec leurs biographies.

Si vous renvoyez tous les articles d'un tableau, vous devrez soit vous limiter à renvoyer un tableau d'identifiants de publication:

[233, 41, 204, 111]

ou renvoyer un tableau massif qui ressemble à quelque chose comme:

[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': '[email protected]', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ]
[id: '2', .....]]

Le premier cas de renvoi d'une liste d'identifiants ne vous est pas très utile, car vous devez alors effectuer un appel API pour chaque identifiant afin d'obtenir des informations sur cette publication.

Le second cas va extraire beaucoup plus d'informations que vous n'en avez besoin 90% du temps et faire beaucoup plus de travail (surtout si l'un de ces champs est très compliqué à construire).

Un objet, d'autre part, peut vous donner accès à toutes les informations dont vous avez besoin, mais ne les a pas encore extraites. La détermination des valeurs des champs peut être effectuée paresseusement (c'est-à-dire lorsque la valeur est nécessaire et pas à l'avance) lors de l'utilisation d'un objet.

  • Les baies exposent plus de données et de capacités que prévu

Revenez à l'exemple du tableau massif renvoyé. Maintenant, quelqu'un peut probablement créer une application qui itère sur chaque valeur à l'intérieur du tableau de publication et l'imprime. Si l'API est mise à jour pour ajouter un seul élément supplémentaire à ce tableau de publication, le code de l'application va se casser car il imprimera un nouveau champ qu'il ne devrait probablement pas. Si l'ordre des éléments dans le tableau de publication renvoyé par l'API change, cela cassera également le code de l'application. Donc, retourner un tableau crée toutes sortes de dépendances possibles qu'un objet ne créerait pas.

  • Fonctionnalité

Un objet peut contenir des informations qui lui permettront de vous fournir des fonctionnalités utiles. Un objet de publication, par exemple, pourrait être suffisamment intelligent pour renvoyer les messages précédents ou suivants. Un tableau ne pourrait jamais faire cela pour vous.

  • Souplesse

Tous les avantages des objets mentionnés ci-dessus contribuent à créer un système plus flexible.

Matt Crinklaw-Vogt
la source
10

Ma question est la suivante: pourquoi utilisent-ils des objets au lieu de tableaux?

Probablement deux raisons:

  • WordPress est assez ancien
  • les tableaux sont plus rapides et prennent moins de mémoire dans la plupart des cas
  • plus facile à sérialiser

Y a-t-il une raison de performance à utiliser un objet?

Non, mais beaucoup d'autres bonnes raisons, par exemple:

  • vous pouvez stocker la logique dans les objets (méthodes, fermetures, etc.)
  • vous pouvez forcer la structure de l'objet en utilisant une interface
  • meilleure autocomplétion dans IDE
  • vous ne recevez pas d'avis pour les clés de tableau non indéfinies
  • à la fin, vous pouvez facilement convertir n'importe quel objet en tableau

POO ! = AOP :)

(Par exemple, dans Ruby, tout est un objet. PHP était auparavant un langage de procédure / script.)

prend
la source
7

WordPress (et un bon nombre d'autres applications PHP) utilisent des objets plutôt que des tableaux, pour des raisons conceptuelles plutôt que techniques.

Un objet (même s'il ne s'agit que d'une instance de stdClass) est une représentation d'une chose. Dans WordPress, cela peut être un article, un commentaire ou un utilisateur. Un tableau, par contre, est une collection de choses. (Par exemple, une liste de publications.)

Historiquement, PHP n'a pas eu une grande prise en charge des objets, donc les tableaux sont devenus assez puissants dès le début. (Par exemple, la possibilité d'avoir des clés arbitraires plutôt que d'être simplement indexées à zéro.) Avec la prise en charge des objets disponible dans PHP 5, les développeurs ont désormais le choix entre utiliser des tableaux ou des objets comme magasins de valeurs-clés. Personnellement, je préfère l'approche WordPress car j'aime la différence syntaxique entre les `` entités '' et les `` collections '' que les objets et les tableaux fournissent.

Seb Pollard
la source
5

Ma question est la suivante: pourquoi (Wordpress) utilise-t-il des objets au lieu de tableaux?

C'est vraiment une bonne question à laquelle il n'est pas facile de répondre. Je ne peux que supposer qu'il est courant dans Wordpress d'utiliser des stdClassobjets car ils utilisent une classe de base de données qui, par défaut, renvoie les enregistrements en tant stdClassqu'objet. Ils s'y sont habitués (8 ans et plus) et c'est tout. Je ne pense pas qu'il y ait beaucoup plus de réflexion derrière le simple fait.

sucre syntaxique pour tableaux associatifs - Zeev Suraski à propos de l'objet standard depuis PHP 3

  • stdClassles objets ne sont pas vraiment meilleurs que les tableaux. Ils sont à peu près les mêmes. C'est pour des raisons historiques de la langue ainsi que les stdClassobjets sont vraiment limités et ne sont en fait qu'une sorte d' objets de valeur dans un sens très basique.
  • stdClassles objets stockent les valeurs de leurs membres comme un tableau le fait par entrée. Et c'est tout.
  • Seuls les monstres de PHP sont capables de créer des stdClassobjets avec des membres privés. Il n'y a pas beaucoup d'avantages - le cas échéant - à le faire.
  • stdClassles objets n'ont pas de méthodes / fonctions. Donc pas d'utilisation de cela dans Wordpress.
  • Par rapport à array, il existe des fonctions beaucoup moins utiles pour traiter une liste ou des données semi-structurées.

Cependant, si vous êtes habitué aux tableaux, lancez simplement:

$array = (array) $object;

Et vous pouvez accéder aux données qui étaient auparavant un objet, sous forme de tableau. Ou vous l'aimez dans l'autre sens:

$object = (object) $array;

Ce qui supprimera uniquement les noms de membres invalides, comme les numéros. Alors faites attention. Mais je pense que vous avez une vue d'ensemble: il n'y a pas beaucoup de différence tant qu'il s'agit de tableaux et d'objets de stdClass.

En relation:

hakre
la source
4
  1. Le code a l'air plus cool de cette façon
  2. Les objets passent par référence
  3. Les objets sont plus typés que les tableaux, d'où les erreurs prononcées (ou vous donnent un message d'erreur significatif lorsque vous essayez d'utiliser un membre non existant)
  4. Tous les IDE d'aujourd'hui ont l'auto-complétion, donc lorsque vous travaillez avec des objets définis, l'EDI fait beaucoup pour vous et accélère les choses
  5. Encapsulez facilement la logique et données dans la même boîte, où avec les tableaux, vous stockez les données dans le tableau, puis utilisez un ensemble de fonctions différentes pour les traiter.
  6. Héritage, si vous avez un tableau similaire avec des fonctionnalités presque mais pas similaires, vous devrez dupliquer plus de code que si vous le faites avec des objets

Probablement une raison de plus à laquelle j'ai pensé

Itay Moav -Malimovka
la source
"# Les objets passent par référence": C'est faux. Les objets ne passent pas comme référence de variable PHP. Ils ne l'ont jamais fait.
hakre
@hakre - êtes-vous sur php4? ou veuillez expliquer ce que vous voulez dire.
Itay Moav -Malimovka
Eh bien non pas que wordpress n'était pas PHP 4 jusqu'à récemment mais en PHP 4 ou PHP 5, les objets ne passent pas comme référence: "Un des points clés de PHP5 OOP qui est souvent évoqué est que" les objets sont passés par références par défaut " . Ce n'est pas tout à fait vrai. Cette section corrige cette pensée générale en utilisant quelques exemples. " Objets et références
hakre
@hakre - Je vois ce que vous voulez dire, mais à toutes fins utiles, le langage se comporte comme si vous ne transmettiez que des références.
Itay Moav -Malimovka
4

Les objets sont beaucoup plus puissants que les tableaux. Chaque objet en tant qu'instance d'une classe peut avoir des fonctions attachées. Si vous avez des données à traiter, vous avez besoin d'une fonction qui effectue le traitement. Avec un tableau, vous devrez appeler cette fonction sur ce tableau et donc associer vous-même la logique aux données. Avec un objet cette association est déjà faite et vous n'avez plus à vous en soucier.

Vous devriez également considérer le principe OO de la dissimulation d'informations. Tout ce qui revient ou va vers la base de données ne doit pas être directement accessible.

Personne ne s'éloigne de SE
la source
Wordpress renvoie les objets de la classe StdClass. Ces objets n'ont rien de commun avec ce que vous mettez en évidence. Ils n'ont pas de fonctions par exemple et ils n'ont pas d'héritage. Et dans le cas de Wordpress, toutes les variables de classe sont publiques.
hakre
Oui c'est vrai. Je pense que dans ce cas, comme d'autres l'ont dit, cela dépend simplement de ce que vous préférez. Je ne suis pas dans wordpress mais ils encapsulent probablement tous les appels de base de données et ne peuvent donc pas fournir de classe spécialisée pour le retour. Mais ma réponse était en général et je pense que des considérations similaires ont été faites par les fabricants ... Ou ils ont juste jeté une pièce.
Personne ne déménage du
Ils utilisent simplement une classe d'assistance de base de données qui renvoie des stdClassobjets par défaut depuis ca. 8 années. Si vous souhaitez obtenir un tableau, vous devez définir un paramètre facultatif pour l'obtenir.
hakre
3

Il existe plusieurs raisons de renvoyer des objets:

  1. L'écriture $myObject->propertynécessite moins de caractères "overhead" que$myArray['element']

  2. L'objet peut renvoyer des données et des fonctionnalités; les tableaux ne peuvent contenir que des données.

  3. Activer le chaînage: $myobject->getData()->parseData()->toXML();

  4. Codage plus facile: la saisie semi-automatique IDE peut fournir des indications de méthode et de propriété pour l'objet.

En termes de performances, les tableaux sont souvent plus rapides que les objets. Outre les performances, il existe plusieurs raisons d'utiliser des tableaux:

  1. La fonctionnalité fournie par la famille de fonctions array _ * () peut réduire la quantité de codage nécessaire dans certains cas.

  2. Des opérations telles que count () et foreach () peuvent être effectuées sur des tableaux. Les objets n'offrent pas cela (sauf s'ils implémentent Iterator ou Countable ).

George Cummins
la source
2

Ce ne sera généralement pas pour des raisons de performances. En règle générale, les objets coûtent plus cher que les tableaux.

Pour beaucoup d'API, cela a probablement à voir avec les objets fournissant d'autres fonctionnalités en plus d'être un mécanisme de stockage. Sinon, c'est une question de préférence et il n'y a vraiment aucun avantage à renvoyer un objet par rapport à un tableau.

Simshaun
la source
En PHP5, la différence de performances entre les tableaux et les objets est marginale.
Justin ᚅᚔᚈᚄᚒᚔ
2

Un tableau n'est qu'un index de valeurs. Alors qu'un objet contient des méthodes qui peuvent générer le résultat pour vous. Bien sûr, parfois vous pouvez accéder directement aux valeurs d'un objet, mais la "bonne façon de le faire" est d'accéder aux méthodes des objets (une fonction opérant sur les valeurs de cet objet).

$obj = new MyObject;
$obj->getName();   // this calls a method (function), so it can decide what to return based on conditions or other criteria

$array['name'];   // this is just the string "name". there is no logic to it. 

Parfois, vous accédez directement aux variables d'un objet, c'est généralement mal vu, mais cela arrive encore assez souvent.

$obj->name;   // accessing the string "name" ... not really different from an array in this case.

Cependant, considérez que la classe MyObject n'a pas de variable appelée 'nom', mais à la place une variable first_name et last_name.

$obj->getName();  // this would return first_name and last_name joined.
$obj->name;  // would fail...
$obj->first_name; 
$obj->last_name; // would be accessing the variables of that object directly.

Ceci est un exemple très simple, mais vous pouvez voir où cela va. Une classe fournit une collection de variables et les fonctions qui peuvent agir sur ces variables au sein d'une entité logique autonome. Une instance de cette entité est appelée un objet, et elle introduit des résultats logiques et dynamiques, ce qu'un tableau n'a tout simplement pas.

Nick Jennings
la source
1

La plupart du temps, les objets sont tout aussi rapides, sinon plus rapides que les tableaux, en PHP, il n'y a pas de différence notable. la raison principale est que les objets sont plus puissants que les tableaux. La programmation orientée objet vous permet de créer des objets et de stocker non seulement des données, mais aussi des fonctionnalités, par exemple en PHP, la classe MySQLi vous permet d'avoir un objet de base de données que vous pouvez manipuler à l'aide d'une multitude de fonctions intégrées, plutôt que de l'approche procédurale.

La raison principale est donc que la POO est un excellent paradigme. J'ai écrit un article sur les raisons pour lesquelles l'utilisation de la POO est une bonne idée, et expliquant le concept, vous pouvez jeter un œil ici: http://tomsbigbox.com/an-introduction-to-oop/

En tant que petit plus, vous tapez également moins pour obtenir des données d'un objet - $ test-> data est meilleur que $ test ['data'].

Tom Walters
la source
1

Je ne suis pas familier avec la presse écrite. Beaucoup de réponses suggèrent ici que la force des objets est leur capacité à contenir du code fonctionnel. Lors du retour d'un objet à partir d'un appel de fonction / API, il ne doit pas contenir de fonctions utilitaires. Juste des propriétés.

La force du renvoi d'objets est que tout ce qui se cache derrière l'API peut changer sans casser votre code.

Exemple: vous obtenez un tableau de données avec des paires clé / valeur, clé représentant la colonne DB. Si la colonne DB est renommée, votre code se cassera.

Josh Johnson
la source
1

Je lance le test suivant en php 5.3.10 (Windows):

for ($i = 0; $i < 1000000; $i++) {
    $x = array();
    $x['a'] = 'a';
    $x['b'] = 'b';
}

et

for ($i = 0; $i < 1000000; $i++) {
    $x = new stdClass;
    $x->a = 'a';
    $x->b = 'b';
}

Copié depuis http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961

Appel de la fonction pour 10 utilisateurs simultanés et 10 fois (pour obtenir une moyenne) puis

  • Tableaux: 100%
  • Objet: 214% - 216% (2 fois plus lent).

AKA, Object c'est encore douloureux lent. La POO garde les choses bien rangées, mais elle doit être utilisée avec précaution.

Qu'est-ce que Wordpress applique ?. Eh bien, les deux solutions utilisent des objets, des tableaux et des objets et des tableaux, la classe wpdb utilise le dernier (et c'est le cœur de Wordpress).

magallanes
la source
Vous devriez voir la comparaison sur PHP 5.4. Les performances des objets sont exceptionnelles et parfois même plus rapides que celles des tableaux.
Sanket Sahu
0

Il suit le principe de boxe et de déballage de la POO. Bien que des langages tels que Java et C # le prennent en charge de manière native, PHP ne le fait pas. Cependant, cela peut être accompli, dans une certaine mesure en PHP, mais pas de manière éloquente car le langage lui-même n'a pas de constructions pour le supporter. Avoir des types de boîte en PHP pourrait aider au chaînage, garder tout orienté objet et permettre une indication de type dans les signatures de méthode. L'inconvénient est la surcharge et le fait que vous avez maintenant des vérifications supplémentaires à faire en utilisant la construction «instanceof». Avoir un système de type est également un plus lors de l'utilisation d'outils de développement dotés d'intellisense ou d'aide au code comme PDT. Plutôt que d'avoir à google / bing / yahoo pour la méthode, elle existe sur l'objet, et vous pouvez utiliser l'outil pour fournir une liste déroulante.

LEMUEL ADANE
la source
0

Bien que les points soulevés sur le fait que les objets sont plus que de simples données sont valides car il s'agit généralement de données et de comportements, il existe au moins un modèle mentionné dans les «Patterns of Enterprise Application Architecture» de Martin Fowler qui s'applique à ce type de cénario dans lequel vous transférez données d'un système (l'application derrière l'API) et d'un autre (votre application).

C'est l' objet de transfert de données - Un objet qui transporte des données entre les processus afin de réduire le nombre d'appels de méthode.

Donc, si la question est de savoir si les API doivent renvoyer un DTO ou un tableau, je dirais que si le coût des performances est négligeable, vous devriez choisir l'option qui est la plus maintenable qui, je dirais, est l'option DTO ... mais bien sûr, vous aussi doivent prendre en compte les compétences et la culture de l'équipe qui développe votre système et le support linguistique ou IDE pour chacune des options.

Vitor Silva
la source