Warum Objekt statt Array zurückgeben?

84

Ich arbeite viel in WordPress und habe festgestellt, dass weit mehr Funktionen Objekte als Arrays zurückgeben. Datenbankergebnisse werden als Objekte zurückgegeben, sofern Sie nicht ausdrücklich nach einem Array fragen. Fehler werden als Objekte zurückgegeben. Außerhalb von WordPress geben Ihnen die meisten APIs ein Objekt anstelle eines Arrays.

Meine Frage ist, warum sie Objekte anstelle von Arrays verwenden. Zum größten Teil spielt es keine große Rolle, aber in einigen Fällen fällt es mir schwerer, Objekte nicht nur zu verarbeiten, sondern meinen Kopf herumzuwickeln. Gibt es einen Leistungsgrund für die Verwendung eines Objekts?

Ich bin ein autodidaktischer PHP-Programmierer. Ich habe einen Abschluss in Geisteswissenschaften. Verzeihen Sie mir, wenn mir ein grundlegender Aspekt der Informatik fehlt. ;)

Dennis
quelle
5
Ich bin neugierig auf die Nachteile von Objekten, wie die Unfähigkeit, sie zu verwenden count()oder array_*()auf ihnen zu funktionieren (zumindest in Bezug auf das Speichern / Zurückgeben von Schlüsseln => Wertdaten). Niemand scheint es zu erwähnen, oder fehlt mir etwas?
Wesley Murch
8
Objekte können durch Implementieren von Countable- oder Iterator-Schnittstellen zählbar und iterierbar gemacht werden. Schauen Sie sich auch php.net/manual/en/book.spl.php an.
Simshaun
Wenn SPL installiert ist und Sie die für Ihre Objektklasse zählbare Schnittstelle implementieren, können Sie count()ein Objekt aufrufen .
Niemand
2
In vielen Fällen ist ein Array nicht einmal sinnvoll, da Sie keine Sammlung von Objekten oder eine Art Sammlung zurückgeben, die mit Arrays nicht einfach emuliert werden kann. Wenn Sie nur eine Folge anderer Werte haben und keine zusätzliche Semantik zugeordnet ist, geben Sie um Gottes Willen ein Array zurück - aber Sie werden feststellen, dass dies selten der Fall ist.
8
@delnan und andere: Bitte beachten Sie, dass @Dennis von assoziativen Arrays (auch bekannt als Dictionaries, auch bekannt als Maps) und nicht von normalen Arrays (Integer-Index) spricht. Diese sind ein Kernmerkmal von PHP und dienen mehr oder weniger dem gleichen Zweck wie dynamische Klassen ( stdClass). Ich bin mir nicht sicher, ob diese Frage eine andere Antwort hat als "Weil Programmierer, die hauptsächlich in OOP arbeiten, die Semantik der Verwendung von Objekten bevorzugen"
BlueRaja - Danny Pflughoeft

Antworten:

62

Dies sind die Gründe, warum ich Objekte im Allgemeinen bevorzuge:

  • Objekte enthalten nicht nur Daten, sondern auch Funktionen.
  • Objekte haben (in den meisten Fällen) eine vordefinierte Struktur. Dies ist sehr nützlich für das API-Design. Darüber hinaus können Sie Eigenschaften als öffentlich, geschützt oder privat festlegen.
  • Objekte passen besser zur objektorientierten Entwicklung.
  • In den meisten IDEs funktioniert die automatische Vervollständigung nur für Objekte.

Hier ist etwas zu lesen:

Sascha Galeere
quelle
3
Der erste Link scheint nicht gut zu sein? Ich meine, es funktioniert, geht aber zu einem anderen Aritcle über
Geo
24

Dies werden Sie wahrscheinlich erst verstehen, wenn Sie mehrere Jahre an einem großen Softwareprojekt gearbeitet haben. Viele neue Informatik-Majors geben Ihnen eine Antwort mit den richtigen Worten (Kapselung, Funktionalität mit Daten und Wartbarkeit), aber nur wenige werden wirklich verstehen, warum all diese Dinge gut zu haben sind.

Lassen Sie uns einige Beispiele durchgehen.

  • Wenn Arrays zurückgegeben wurden, müssen entweder alle Werte im Voraus berechnet werden oder es müssen viele kleine Werte zurückgegeben werden, aus denen Sie die komplexeren Werte erstellen können.

Denken Sie an eine API-Methode, die eine Liste von WordPress-Posts zurückgibt. Diese Beiträge haben alle Autoren, Autoren haben Namen, E-Mail-Adresse, vielleicht sogar Profile mit ihren Biografien.

Wenn Sie alle Beiträge in einem Array zurückgeben, müssen Sie sich entweder darauf beschränken, ein Array von Beitrags-IDs zurückzugeben:

[233, 41, 204, 111]

oder ein massives Array zurückgeben, das ungefähr so ​​aussieht:

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

Der erste Fall der Rückgabe einer Liste von IDs ist für Sie nicht sehr hilfreich, da Sie dann für jede ID einen API-Aufruf durchführen müssen, um Informationen zu diesem Beitrag zu erhalten.

Im zweiten Fall werden viel mehr Informationen abgerufen, als Sie in 90% der Fälle benötigen, und es wird viel mehr Arbeit geleistet (insbesondere, wenn eines dieser Felder sehr kompliziert zu erstellen ist).

Ein Objekt hingegen kann Ihnen Zugriff auf alle benötigten Informationen gewähren, hat diese Informationen jedoch noch nicht abgerufen. Das Bestimmen der Werte von Feldern kann bei Verwendung eines Objekts träge erfolgen (dh wenn der Wert benötigt wird und nicht vorher).

  • Arrays stellen mehr Daten und Funktionen zur Verfügung als beabsichtigt

Kehren Sie zum Beispiel des zurückgegebenen massiven Arrays zurück. Jetzt kann wahrscheinlich jemand eine Anwendung erstellen, die über jeden Wert innerhalb des Post-Arrays iteriert und ihn druckt. Wenn die API aktualisiert wird, um nur ein zusätzliches Element zu diesem Post-Array hinzuzufügen, wird der Anwendungscode unterbrochen, da ein neues Feld gedruckt wird, das wahrscheinlich nicht gedruckt werden sollte. Wenn sich die Reihenfolge der von der API zurückgegebenen Elemente im Post-Array ändert, wird auch der Anwendungscode beschädigt. Die Rückgabe eines Arrays erzeugt also alle möglichen Abhängigkeiten, die ein Objekt nicht erzeugen würde.

  • Funktionalität

Ein Objekt kann Informationen enthalten, die es Ihnen ermöglichen, nützliche Funktionen bereitzustellen. Ein Post-Objekt könnte beispielsweise intelligent genug sein, um die vorherigen oder nächsten Posts zurückzugeben. Ein Array könnte das niemals für Sie tun.

  • Flexibilität

Alle Vorteile der oben genannten Objekte tragen zur Schaffung eines flexibleren Systems bei.

Matt Crinklaw-Vogt
quelle
10

Meine Frage ist, warum sie Objekte anstelle von Arrays verwenden.

Wahrscheinlich zwei Gründe:

  • WordPress ist ziemlich alt
  • Arrays sind schneller und benötigen in den meisten Fällen weniger Speicher
  • einfacher zu serialisieren

Gibt es einen Leistungsgrund für die Verwendung eines Objekts?

Nein, aber viele gute andere Gründe, zum Beispiel:

  • Sie können Logik in den Objekten speichern (Methoden, Abschlüsse usw.)
  • Sie können die Objektstruktur über eine Schnittstelle erzwingen
  • Bessere Autovervollständigung in IDE
  • Sie erhalten keine Benachrichtigungen für nicht undefinierte Array-Schlüssel
  • Am Ende können Sie jedes Objekt leicht in ein Array konvertieren

OOP ! = AOP :)

(In Ruby ist beispielsweise alles ein Objekt. PHP war zuvor eine prozedurale / Skriptsprache.)

Takeshin
quelle
7

WordPress (und eine ganze Reihe anderer PHP-Anwendungen) verwenden eher Objekte als Arrays, eher aus konzeptionellen als aus technischen Gründen.

Ein Objekt (auch wenn es nur eine Instanz von stdClass ist) ist eine Darstellung einer Sache. In WordPress kann dies ein Beitrag, ein Kommentar oder ein Benutzer sein. Ein Array hingegen ist eine Sammlung von Dingen. (Zum Beispiel eine Liste von Beiträgen.)

In der Vergangenheit hatte PHP keine großartige Objektunterstützung, so dass Arrays schon früh ziemlich leistungsfähig wurden. (Zum Beispiel die Möglichkeit, beliebige Schlüssel zu haben, anstatt nur nullindiziert zu sein.) Mit der in PHP 5 verfügbaren Objektunterstützung haben Entwickler jetzt die Wahl zwischen der Verwendung von Arrays oder Objekten als Schlüsselwertspeicher. Persönlich bevorzuge ich den WordPress-Ansatz, da mir der syntaktische Unterschied zwischen "Entitäten" und "Sammlungen", den Objekte und Arrays bieten, gefällt.

Seb Pollard
quelle
5

Meine Frage ist, warum sie (Wordpress) Objekte anstelle von Arrays verwenden.

Das ist wirklich eine gute Frage und nicht einfach zu beantworten. Ich kann nur davon ausgehen, dass es in Wordpress üblich ist, stdClassObjekte zu verwenden , da diese eine Datenbankklasse verwenden, die standardmäßig Datensätze als stdClassObjekt zurückgibt . Sie haben sich daran gewöhnt (8 Jahre und mehr) und das war's. Ich glaube nicht, dass hinter der einfachen Tatsache viel mehr Gedanken stecken.

syntaktischer Zucker für assoziative Arrays - Zeev Suraski über das Standardobjekt seit PHP 3

  • stdClassObjekte sind nicht wirklich besser als Arrays. Sie sind ziemlich gleich. Das ist aus einigen historischen Gründen der Sprache so, dass stdClassObjekte wirklich begrenzt sind und eigentlich nur eine Art Wertobjekt in einem sehr grundlegenden Sinne sind.
  • stdClassObjekte speichern Werte für ihre Mitglieder wie ein Array pro Eintrag. Und das ist es.
  • Nur PHP-Freaks können stdClassObjekte mit privaten Mitgliedern erstellen . Es gibt nicht viel Nutzen - wenn überhaupt - dies zu tun.
  • stdClassObjekte haben keine Methoden / Funktionen. Also keine Verwendung davon in Wordpress.
  • Im Vergleich zu arraygibt es weit weniger hilfreiche Funktionen, um mit einer Liste oder halbstrukturierten Daten umzugehen.

Wenn Sie jedoch an Arrays gewöhnt sind, setzen Sie einfach Folgendes um:

$array = (array) $object;

Und Sie können auf die Daten zugreifen, die zuvor ein Objekt waren, als Array. Oder du magst es umgekehrt:

$object = (object) $array;

Dadurch werden nur ungültige Mitgliedsnamen wie Zahlen gelöscht. Also pass auf dich auf. Aber ich denke, Sie bekommen das große Bild: Es gibt keinen großen Unterschied, solange es um Arrays und Objekte von geht stdClass.

Verbunden:

hakre
quelle
4
  1. Der Code sieht auf diese Weise cooler aus
  2. Objekte werden als Referenz übergeben
  3. Objekte sind stärker typisiert als Arrays, daher kann es zu Fehlern kommen (oder Sie erhalten eine aussagekräftige Fehlermeldung, wenn Sie versuchen, nicht vorhandene Elemente zu verwenden).
  4. Alle IDEs werden heute automatisch vervollständigt. Wenn Sie also mit definierten Objekten arbeiten, leistet die IDE viel für Sie und beschleunigt die Arbeit
  5. Kapselung von Logik und Daten in derselben Box, in der Sie mit Arrays die Daten im Array speichern und dann mit einer Reihe verschiedener Funktionen verarbeiten.
  6. Vererbung: Wenn Sie ein ähnliches Array mit fast, aber nicht ähnlichen Funktionen hätten, müssten Sie mehr Code duplizieren, als wenn Sie dies mit Objekten tun würden

Wahrscheinlich ein Grund mehr, über den ich nachgedacht habe

Itay Moav-Malimovka
quelle
"# Objekte werden als Referenz übergeben": Das ist falsch. Objekte werden nicht als PHP-Variablenreferenz übergeben. Sie haben es nie getan.
hakre
@hakre - bist du auf php4? oder erläutern Sie bitte, was Sie meinen.
Itay Moav-Malimovka
Nun, nicht, dass WordPress bis vor kurzem nicht PHP 4 war, aber in PHP 4 oder PHP 5 werden Objekte nicht als Referenz übergeben: "Einer der Schlüsselpunkte von PHP5 OOP, der oft erwähnt wird, ist, dass" Objekte standardmäßig als Referenz übergeben werden ". Dies ist nicht ganz richtig. Dieser Abschnitt korrigiert diesen allgemeinen Gedanken anhand einiger Beispiele. " Objekte und Referenzen
hakre
@hakre - Ich verstehe, was Sie meinen, aber für alle Zwecke verhält sich die Sprache so, als würden Sie nur Referenzen übergeben.
Itay Moav-Malimovka
4

Objekte sind viel leistungsfähiger als Arrays. An jedes Objekt als Instanz einer Klasse können Funktionen angehängt werden. Wenn Sie Daten haben, die verarbeitet werden müssen, benötigen Sie eine Funktion, die die Verarbeitung ausführt. Bei einem Array müssten Sie diese Funktion für dieses Array aufrufen und daher die Logik selbst den Daten zuordnen. Mit einem Objekt ist diese Zuordnung bereits abgeschlossen und Sie müssen sich nicht mehr darum kümmern.

Sie sollten auch das OO-Prinzip des Versteckens von Informationen berücksichtigen. Nicht alles, was aus der Datenbank zurückkommt oder in die Datenbank gelangt, sollte direkt zugänglich sein.

Niemand
quelle
Wordpress gibt Objekte der Klasse zurück StdClass. Diese Objekte haben nichts gemeinsam mit dem, was Sie hervorheben. Sie haben zum Beispiel keine Funktionen und sie haben keine Vererbung. Und im Fall von Wordpress sind alle Klassenvariablen öffentlich.
hakre
Ja, das ist wahr. Ich denke, in diesem Fall hängt es, wie andere sagten, nur davon ab, was Sie bevorzugen. Ich mag WordPress nicht, aber wahrscheinlich kapseln sie alle Datenbankaufrufe und können daher keine spezielle Klasse für die Rückgabe bereitstellen. Aber meine Antwort war im Allgemeinen und ich denke, die Macher haben ähnliche Überlegungen angestellt ... Oder sie haben einfach eine Münze geworfen.
Niemand
Sie verwenden nur eine Datenbank-Hilfsklasse, die stdClassstandardmäßig Objekte zurückgibt . 8 Jahre. Wenn Sie ein Array abrufen möchten, müssen Sie einen optionalen Parameter festlegen, um es abzurufen.
hakre
3

Es gibt mehrere Gründe, Objekte zurückzugeben:

  1. Das Schreiben $myObject->propertyerfordert weniger "Overhead" -Zeichen als$myArray['element']

  2. Das Objekt kann Daten und Funktionen zurückgeben. Arrays können nur Daten enthalten.

  3. Verkettung aktivieren: $myobject->getData()->parseData()->toXML();

  4. Einfachere Codierung: Die automatische Vervollständigung von IDE kann Hinweise zu Methoden und Eigenschaften für Objekte bereitstellen.

In Bezug auf die Leistung sind Arrays häufig schneller als Objekte. Neben der Leistung gibt es mehrere Gründe, Arrays zu verwenden:

  1. Die von der Funktionsfamilie des Arrays _ * () bereitgestellte Funktionalität kann in einigen Fällen den Codierungsaufwand verringern.

  2. Operationen wie count () und foreach () können für Arrays ausgeführt werden. Objekte bieten dies nicht an (es sei denn, sie implementieren Iterator oder Countable ).

George Cummins
quelle
2

Dies wird normalerweise aus Leistungsgründen nicht der Fall sein. In der Regel kosten Objekte mehr als Arrays.

Bei vielen APIs hat dies wahrscheinlich damit zu tun, dass die Objekte neben dem Speichermechanismus noch andere Funktionen bieten. Andernfalls ist es eine Frage der Präferenz und es gibt wirklich keinen Vorteil, ein Objekt gegenüber einem Array zurückzugeben.

Simshaun
quelle
In PHP5 ist der Leistungsunterschied zwischen Arrays und Objekten gering.
Justin 15
2

Ein Array ist nur ein Index von Werten. Während ein Objekt Methoden enthält, die das Ergebnis für Sie generieren können. Sicher, manchmal können Sie direkt auf Objektwerte zugreifen, aber der "richtige Weg" besteht darin, auf Objektmethoden zuzugreifen (eine Funktion, die mit den Werten dieses Objekts arbeitet).

$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. 

Manchmal greifen Sie direkt auf Objektvariablen zu, dies wird normalerweise verpönt, aber es kommt immer noch ziemlich oft vor.

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

Beachten Sie jedoch, dass die MyObject-Klasse keine Variable mit dem Namen 'name' hat, sondern eine Variable mit Vorname und Nachname.

$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.

Dies ist ein sehr einfaches Beispiel, aber Sie können sehen, wohin das führt. Eine Klasse stellt eine Sammlung von Variablen und die Funktionen bereit, die diese Variablen innerhalb einer in sich geschlossenen logischen Entität verarbeiten können. Eine Instanz dieser Entität wird als Objekt bezeichnet und führt logische und dynamische Ergebnisse ein, die ein Array einfach nicht hat.

Nick Jennings
quelle
1

Meistens sind Objekte genauso schnell, wenn nicht sogar schneller als Arrays. In PHP gibt es keinen merklichen Unterschied. Der Hauptgrund ist, dass Objekte leistungsfähiger sind als Arrays. Mit der objektorientierten Programmierung können Sie Objekte erstellen und nicht nur Daten, sondern auch Funktionen darin speichern. In PHP können Sie beispielsweise mit der MySQLi-Klasse über ein Datenbankobjekt verfügen, das Sie mithilfe einer Vielzahl integrierter Funktionen anstelle des prozeduralen Ansatzes bearbeiten können.

Der Hauptgrund ist also, dass OOP ein ausgezeichnetes Paradigma ist. Ich habe einen Artikel darüber geschrieben, warum die Verwendung von OOP eine gute Idee ist. Wenn Sie das Konzept erläutern, können Sie hier einen Blick darauf werfen: http://tomsbigbox.com/an-introduction-to-oop/

Als kleines Plus geben Sie auch weniger ein, um Daten von einem Objekt abzurufen - $ test-> data ist besser als $ test ['data'].

Tom Walters
quelle
1

Ich bin mit WordPress nicht vertraut. Viele Antworten deuten darauf hin, dass eine Stärke von Objekten darin besteht, Funktionscode zu enthalten. Wenn ein Objekt von einem Funktions- / API-Aufruf zurückgegeben wird, sollte es keine Dienstprogrammfunktionen enthalten. Nur Eigenschaften.

Die Stärke bei der Rückgabe von Objekten besteht darin, dass sich alles, was sich hinter der API befindet, ändern kann, ohne Ihren Code zu beschädigen.

Beispiel: Sie erhalten ein Datenarray mit Schlüssel / Wert-Paaren, wobei der Schlüssel die DB-Spalte darstellt. Wenn die DB-Spalte umbenannt wird, wird Ihr Code unterbrochen.

Josh Johnson
quelle
1

Ich führe den nächsten Test in PHP 5.3.10 (Windows) aus:

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

und

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

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

Aufruf der Funktion für 10 gleichzeitige Benutzer und 10 Mal (um einen Durchschnitt zu erhalten)

  • Arrays: 100%
  • Objekt: 214% - 216% (2 mal langsamer).

AKA, Objekt es ist immer noch schmerzhaft langsam. OOP sorgt für Ordnung, sollte jedoch vorsichtig verwendet werden.

Welches Wordpress bewirbt sich?. Nun, beide Lösungen verwenden Objekte, Arrays und Object & Arrays, die Klasse wpdb verwendet das spätere (und es ist das Herz von Wordpress).

Magallane
quelle
Sie sollten den Vergleich auf PHP 5.4 sehen. Die Leistung von Objekten ist hervorragend und manchmal sogar schneller als bei Arrays.
Sanket Sahu
0

Es folgt dem Box- und Unboxing-Prinzip von OOP. Während Sprachen wie Java und C # dies nativ unterstützen, tut PHP dies nicht. Es kann jedoch bis zu einem gewissen Grad in PHP erreicht werden, nur nicht eloquent, da die Sprache selbst keine Konstrukte hat, die dies unterstützen. Box-Typen in PHP können bei der Verkettung helfen, alles objektorientiert halten und Typanweisungen in Methodensignaturen ermöglichen. Der Nachteil ist der Overhead und die Tatsache, dass Sie jetzt zusätzliche Überprüfungen durchführen müssen, um das Konstrukt "instanceof" zu verwenden. Ein Typsystem ist auch ein Plus bei der Verwendung von Entwicklungstools mit Intellisense- oder Code-Unterstützung wie PDT. Anstatt für die Methode google / bing / yahoo zu müssen, ist sie für das Objekt vorhanden, und Sie können das Tool verwenden, um ein Dropdown-Menü bereitzustellen.

LEMUEL ADANE
quelle
0

Obwohl die Punkte, die gemacht werden, dass Objekte mehr als nur Daten sind, gültig sind, da es sich normalerweise um Daten und Verhalten handelt, wird in Martin Fowlers "Patterns of Enterprise Application Architecture" mindestens ein Muster erwähnt , das für diese Art von Szenario gilt, in dem Sie übertragen Daten von einem System (der Anwendung hinter der API) und einem anderen (Ihrer Anwendung).

Es ist das Datenübertragungsobjekt - Ein Objekt, das Daten zwischen Prozessen überträgt, um die Anzahl der Methodenaufrufe zu reduzieren.

Wenn die Frage ist, ob APIs ein DTO oder ein Array zurückgeben sollen, würde ich sagen, wenn die Leistungskosten vernachlässigbar sind, sollten Sie die Option wählen, die wartbarer ist, was meiner Meinung nach die DTO-Option ist ... aber natürlich auch Sie Sie müssen die Fähigkeiten und die Kultur des Teams berücksichtigen, das Ihr System entwickelt, sowie die Sprach- oder IDE-Unterstützung für jede der Optionen.

Vitor Silva
quelle