PHP ist eine gemischte Paradigmasprache, mit der Datentypen, die keine Objekte sind, wie z. B. Arrays, verwendet und zurückgegeben werden können. Ich stelle eine Frage, um zu versuchen, einige Richtlinien für die Auswahl von Arrays gegenüber Objekten zu klären, wenn ich mich für ein Programmierkonstrukt in einer bestimmten Situation entscheide.
Dies ist wirklich eine Frage zu Möglichkeiten, Daten mithilfe von PHP-Sprachkonstrukten zu codieren, und zu der Frage, ob eine Möglichkeit für die Datenübermittlung (d. H. Serviceorientierte Architektur oder Webservices) wahrscheinlicher als eine andere gewählt werden soll.
Beispiel
Angenommen, Sie haben einen Artikeltyp bestehend aus {cost, name, part_number, item_count}. Ihr Programm fordert die Anzeige mehrerer solcher Elementtypen an, in denen Sie ein Array als äußeren Container für die einzelnen Elementtypen verwenden möchten. [Sie können auch PHP ArrayObject
für das OO-Paradigma verwenden, aber meine Frage bezieht sich nicht auf dieses (äußere) Array]. Meine Frage ist, wie die Artikeltypdaten zu codieren sind und welches Paradigma zu verwenden ist. Mit PHP können Sie PHP Native Arrays
oder verwenden PHP Objects
.
Ich kann solche Daten auf zwei Arten kodieren:
//PHP's associative arrays:
$ret = array(
0 => array(
'cost' => 10.00,
'name' => 'item1',
'part_number' => 'zyz-100',
'item_count' => 15
),
1 => array(
'cost' => 34.00,
'name' => 'item2',
'part_number' => 'abc-230',
'item_count' => 42
),
);
vs
//here ItemType is encapsulated into an object
$ret = array(
0 => new ItemType(10.00, 'item1', 'zyz-100', 15),
1 => new ItemType(34.00, 'item2', 'abc-230', 42),
);
class ItemType
{
private $price;
private $name;
private $partNumber;
private $itemCount;
function __construct($price, $name, $partNumber, $itemCount) {..}
}
Was ich denke
Die Array-Codierung ist leicht und JSON-fähiger, kann jedoch leichter durcheinander gebracht werden. Wenn Sie einen der assoziativen Array-Schlüssel falsch schreiben, liegt möglicherweise ein Fehler vor, der schwerer abzufangen ist. Aber es ist auch einfacher, aus einer Laune heraus zu wechseln. Angenommen, ich möchte nicht item_count
mehr speichern , ich kann jede Textverarbeitungssoftware verwenden, um auf einfache Weise alle item_count
Instanzen im Array zu entfernen und dann andere Funktionen zu aktualisieren, die sie entsprechend verwenden. Es mag ein langwieriger Prozess sein, aber es ist einfach.
Die objektorientierte Codierung ruft die IDE- und PHP-Sprachfunktionen auf und erleichtert das Abfangen von Fehlern im Voraus, ist jedoch in erster Linie schwieriger zu programmieren und zu codieren. Ich sage es härter, weil Sie ein wenig über Ihre Objekte nachdenken und vorausdenken müssen und die OO-Codierung eine etwas höhere kognitive Belastung erfordert als das Schreiben von Array-Strukturen. Das heißt, wenn es einmal codiert ist, können einige Änderungen in gewissem Sinne einfacher implementiert werden, da zum Entfernen item_count
beispielsweise weniger Codezeilen erforderlich sind. Änderungen selbst können jedoch im Vergleich zur Array-Methode noch eine höhere kognitive Belastung erfordern, da übergeordnete OO-Einrichtungen beteiligt sind.
Frage
In einigen Fällen ist es klar, wie in Fällen, in denen ich Manipulationen an den Daten vornehmen muss. In einigen Fällen, in denen ich nur ein paar Zeilen mit "Artikeltyp" -Daten speichern muss, kann ich mich nicht auf klare Richtlinien oder Überlegungen stützen, um zu entscheiden, ob Arrays verwendet oder Objekte erstellt werden sollen. Es scheint, als könnte ich einfach eine Münze werfen und eine auswählen. Ist das hier der Fall?
(object)['foo'=>'bar']
. Der resultierende Wert hat die KlasseStdClass
, wird in seiner Gesamtheit von JSON-codiertjson_encode()
und Eigenschaften können genauso einfach umbenannt werden wie Array-Indizes (was nicht immer so einfach ist, wenn indirekt über eine Variable darauf zugegriffen wird). Es gibt jedoch unterschiedliche Operationen für solche Werte. Sie haben beispielsweise keine Objekt-Unions, wie Sie Array-Unions haben, und Sie können diearray_*()
Funktionen nicht direkt verwenden .array
, 2:User-defined Class
, 3:stdClass
. Die Leistung in Bezug auf die Geschwindigkeit ist im Vergleicharray
mit aUser-defined class
(wie z. B. IhrerItemType
) ziemlich gleich , aber definierteclass
es belegen tendenziell weniger Speicher alsarray
s.stdClass
Auf der anderen Seite ist die langsamste der drei Optionen und verwendet auch den meisten Speicher.Antworten:
Wie ich das sehe, hängt davon ab, was Sie danach mit den Daten machen wollen. Anhand einiger einfacher Überprüfungen können Sie feststellen, welche der beiden Datenstrukturen für Sie besser ist:
Haben diese Daten eine Logik?
Wird zum Beispiel
$price
eine ganze Zahl von Cent gespeichert, so hätte ein Produkt mit einem Preis von 9,99 USDprice = 999
und nichtprice = 9.99
? (Wahrscheinlich ja) Oder musspartNumber
eine bestimmte Regex übereinstimmen? Oder müssen Sie in der Lage sein, leicht zu überprüfen, ob dasitemCount
in Ihrem Inventar verfügbar ist? Müssen Sie diese Funktionen in Zukunft ausführen? In diesem Fall ist es am besten, jetzt eine Klasse zu erstellen. Dies bedeutet, dass Sie Integritätsbedingungen und Logik definieren können, die in die Datenstruktur integriert sind:private $myPrice
ist auf gesetzt, gibt999
aber$item->getPriceString()
zurück$9.99
und$item->inStock()
steht zum Aufrufen in Ihrer Anwendung zur Verfügung.Übergeben Sie diese Daten an mehrere PHP-Funktionen?
Wenn ja, dann benutze eine Klasse. Wenn Sie diese Daten einmal generieren, um einige Transformationen durchzuführen, oder um sie einfach als JSON-Daten an eine andere Anwendung (JavaScript oder auf andere Weise) zu senden, ist ein Array die einfachere Wahl. Wenn Sie jedoch mehr als zwei PHP-Funktionen haben, die diese Daten als Parameter akzeptieren, verwenden Sie eine Klasse. Wenn nichts anderes, können Sie damit definieren
someFunction(MyProductClass $product) {
und es ist sehr klar, was Ihre Funktionen als Eingabe erwarten. Wenn Sie Ihren Code skalieren und über mehr Funktionen verfügen, ist es viel einfacher zu wissen, welche Art von Daten jede Funktion akzeptiert. SehensomeFunction($someArrayData) {
ist bei weitem nicht so klar. Dies erzwingt auch keine Typenkonsistenz und bedeutet, dass (wie Sie sagten) die flexible Struktur des Arrays später zu Entwicklungsproblemen führen kannBauen Sie eine Bibliothek oder eine gemeinsam genutzte Codebasis auf?
Wenn ja, benutze eine Klasse! Denken Sie an einen neuen Entwickler, der Ihre Bibliothek verwendet, oder an einen anderen Entwickler in der Firma, der Ihren Code noch nie zuvor verwendet hat. Es ist für sie viel einfacher, sich eine Klassendefinition anzusehen und zu verstehen, was diese Klasse tut, oder eine Reihe von Funktionen in Ihrer Bibliothek zu sehen, die Objekte einer bestimmten Klasse akzeptieren, als zu erraten, welche Struktur sie in einer Klasse generieren müssen Anzahl der Arrays. Dies betrifft auch die Probleme mit der Datenkonsistenz bei Nummer 1: Wenn Sie eine Bibliothek oder eine gemeinsam genutzte Codebasis entwickeln, seien Sie nett zu Ihren Benutzern: Geben Sie ihnen Klassen, die die Datenkonsistenz erzwingen, und schützen Sie sie vor Fehlern beim Entwurf Ihrer Daten .
Ist dies ein kleiner Teil einer Anwendung oder nur eine Transformation von Daten? Passen Sie nicht in eines der oben genannten?
Eine Klasse könnte zu viel sein; Verwenden Sie ein Array, wenn es Ihnen passt und Sie es leichter finden. Wie oben erwähnt, sollten Sie sich nicht mit einer Klasse befassen, wenn Sie nur strukturierte Daten zum Senden als JSON, YAML oder XML oder was auch immer generieren, es sei denn, dies ist erforderlich. Wenn Sie ein kleines Modul in einer größeren Anwendung schreiben und keine anderen Module / Teams mit Ihrem Code kommunizieren müssen, ist möglicherweise ein Array ausreichend.
Berücksichtigen Sie letztendlich die Skalierungsanforderungen Ihres Codes und berücksichtigen Sie, dass ein strukturiertes Array zwar eine schnelle Lösung darstellt, eine Klasse jedoch eine wesentlich stabilere und skalierbarere Lösung darstellt.
json_data()
Beachten Sie außerdem Folgendes: Wenn Sie eine Klasse haben und in JSON ausgeben möchten, gibt es keinen Grund, warum Sie keine Methode Ihrer Klasse definieren können, die ein JSON-fähiges Array der Daten in der Klasse zurückgibt. Das habe ich in meinen PHP-Anwendungen gemacht, in denen ich Klassendaten als JSON senden musste. Als Beispiel:quelle
my_lineitems
, sie per Referenz abzurufen, da Variablen nur einen Bezeichner für das Objekt enthalten, nicht für das Objekt selbst. php.net/manual/en/language.oop5.references.phpSie können die Json- Struktur mithilfe der JsonSerializable- Schnittstelle implementieren und verschachtelte Arrays / Klassen auf beliebige Weise verwenden. Class ist schneller in get / set-Operationen und einfacher zu debuggen. Bei Array brauchen Sie keine Deklaration.
quelle
json_encode(['order'=>$o]);
in existsing akzeptierte Antwort ist leer:{"order":{}}
. Sicher können Sie verwenden:$o->forJSON()
jedes Mal auf jedem Objekt auf jeder Ebene, aber es ist nicht wirklich gutes Design. Weil du die ganze Zeit etwas schreiben musst wie:$items_json = array(); foreach($this->my_lineitems as $item) $items_json[] = $item->forJSON();