Überprüfen Sie, ob sich ein Objekt geändert hat

9

Gibt es eine nativere Methode (z. B. eine integrierte Funktion) mit weniger Benutzerlandcode, um zu überprüfen, ob sich die Werte einer Objekteigenschaft geändert haben, anstatt eine dieser Methoden zu verwenden:

Der Serialisierungsansatz

%Vor%

Was ergibt:

%Vor%

Der Schattenkopie-Ansatz

%Vor%

Was ergibt:

%Vor%

Beide Ansätze funktionieren. Beide haben jedoch Nachteile gegenüber einer Nicht-Nutzerland-Implementierung. Die erste benötigt eine CPU für Serialisierung und Hashing und die zweite benötigt Speicher zum Speichern von Klonen. Und einige Klassen dürfen nicht geklont werden.

Verfolgt PHP Änderungen an Objekteigenschaften nicht? Und stellt PHP keine Methode zur Verfügung, um davon Gebrauch zu machen?

    
TiMESPLiNTER 24.02.2015, 08:36
quelle

3 Antworten

2

Was möchten Sie tun?

Sie versuchen, nach einer Kette von "unbekannten" Operationen das Objekt mit sich selbst zu vergleichen, um zu überprüfen, ob sich das Objekt geändert hat. Wenn dies zutrifft, müssen einige logische Punkte beachtet werden. Wenn Sie zuerst ein Objekt mit sich selbst vergleichen wollen, haben Sie nur zwei Möglichkeiten:

  1. Merken Sie sich den gesamten Objektstatus (zum Beispiel Hash, oder kopieren Sie einfach das ganze Objekt)
  2. Verfolgen Sie Änderungen im Laufe der Zeit

Es gibt keinen anderen logischen Ansatz. Vergleichen von Speicherzuordnungen, realen Objekten, Kopieren von Objekten, Vergleichen von Hashes ist alles in Punkt eins. Verfolgen von Änderungen, Speichern von Änderungen innerhalb des Objekts, Erinnern an Zwischenzeitoperationen, innerhalb von Punkt 2.

Meiner Meinung nach ist diese Frage eine Art Datenfrage. In diesem Fall gibt es viele, viele Lösungen, aber keine von ihnen ist in PHP soweit festgeschrieben. Warum?

Die Antwort ist einfach. PHP-Leute haben die gleichen Probleme, die du hast:). Wenn dies innerhalb von PHP behoben wäre, sollte php einen dieser Mechanismen (1) oder (2) benutzen.

In diesem Fall sollte jedes Objekt, das Sie erstellen, und jede Operation, die Sie gemacht haben, irgendwo geschrieben werden, um sich an jeden Zustand / jedes Objekt / etwas zu erinnern und sie für zukünftige Vergleiche zu verwenden.

Obwohl Sie diese Lösung benötigen, tun fast ~100% der Websites nicht. So hardcoding dies innerhalb von PHP würde ~100% der Websites arbeiten langsamer und Ihre Arbeit schneller gemacht;).

PHP hypothetische Lösung?

Die einzige Lösung (vielleicht in PHP in der Zukunft gebaut) kann ich eine php config-Flag machen: track objects , und nur wenn dieses Flag true ist, dann führe alle php-Mechanismen des Tracking aus Objekte Staaten. Aber das bedeutet auch eine große Leistungslücke. Wie alle ifs (wenn Tracking, Tracking, Tracking) auch Prozessor und Speicher zeitaufwendig sind.

Es gibt auch ein Problem, was zu vergleichen? Sie müssen Objekt mit demselben Objekt vergleichen, aber ... Vor ein paar Minuten? Wenige Operationen her? Nein ... Sie müssen genau einen Platz im Code angeben und dann im Code auf den zweiten Platz zeigen und das Objekt an diesen beiden Stellen vergleichen. So hypothetische Auto-Tracking ist ... Art von machtlos, da es keinen Schlüssel im Objektstatus von Zeit -Array gibt. Ich meine, auch wenn Sie% co_de haben % Funktion, wie sollte es aussehen?

%Vor%

Leider bleibt Ihnen eine eigene Implementierung ...

Schließlich würde ich vorschlagen, dafür einen eigenen Mechanismus zu implementieren, und erinnere mich , es nur dort zu verwenden, wo du es brauchst. Da dieser Mechanismus sicherlich zeit- und speicherintensiv sein wird. Also denke sorgfältig nach:

  1. Welche Objekte möchten Sie vergleichen? Warum?
  2. Wenn Sie sie vergleichen möchten?
  3. Müssen alle Änderungen verglichen werden?
  4. Was ist der einfachste Weg, diese Statusänderungen zu speichern?

Und nach alldem versuchen Sie es zu implementieren. Ich sehe, dass du ein riesiges PHP-Wissen hast, also bin ich mir ziemlich sicher, dass du etwas herausfinden wirst. Es gibt auch viele Kommentare und mögliche Ideen in dieser Frage und Diskussion.

Aber vielleicht habe ich ein wenig erklärt, warum, es gibt keine eingebaute Lösung und warum sollte es in Zukunft keine geben ...:).

AKTUALISIEREN

Schauen Sie hier: Ссылка . Dies ist eine großartige Ressource über PHP-Muster. Sie sollten sich die Optionen Adapter , Decorator und Beobachter für mögliche elegante objektorientierte Lösungen ansehen.

    
Jacek Kowalewski 24.02.2015, 11:47
quelle
1

Während ich auch nach einem sehr schnellen / schnelleren Ansatz suche, ist eine Variante von Methode 2 effektiv, was ich benutze. Der Vorteil dieser Methode ist, dass sie (ziemlich) schnell ist (im Vergleich zu einem isset ()), abhängig von der Objektgröße. Und Sie müssen nicht daran denken, bei jedem Ändern des Objekts eine ->modified -Eigenschaft festzulegen.

%Vor%

Das ist im Grunde Methode 2, aber ohne den Klon. Wenn Ihr Eigenschaftswert ein anderes Objekt (vobj) ist, dann ist möglicherweise ein Klon notwendig (andernfalls verweisen beide Referenzen auf das gleiche Objekt), aber es ist erwähnenswert, dass es das Objekt vobj ist, das Sie wollen Sehen Sie, ob sich mit dem obigen Code geändert hat. Die Sache mit Klon ist, dass es ein zweites Objekt konstruiert (ähnliche Leistung), aber wenn Sie sehen wollen, welche Werte sich geändert haben, interessiert Sie nicht das Objekt selbst, sondern nur die Werte. Und Array-Casting eines Objekts ist sehr schnell (~ 2x die Geschwindigkeit eines Boolean Cast eines Bool). Nun, bis zu großen Objekten. Auch der direkte Array-Vergleich === ist sehr schnell, für Arrays unter zB 100 Vals.

Ich bin mir ziemlich sicher, dass eine noch schnellere Methode existiert ...

    
Beracah 21.10.2016 21:48
quelle
0

Es gibt keine eingebaute Methode, fürchte ich. Der Schattenkopie-Ansatz ist der beste Weg.

Wenn Sie die Klasse kontrollieren möchten, können Sie eine modified Variable hinzufügen:

%Vor%

Wenn ich das Objekt in irgendeiner Weise modifiziere, verwende ich einfach

%Vor%

So kann ich später überprüfen

%Vor%

um zu überprüfen, ob es geändert wurde. Denken Sie daran, vor dem Speichern von Inhalten in einer Datenbank unset($obj->modified) zu speichern.

    
Mooseman 24.02.2015 11:27
quelle

Tags und Links