dedlfix: mit __set() array property bauen?

Beitrag lesen

Tach!

Das ist das von mir erwünschte ergebis. Was hast du denn gedacht, was ich meine?

Ich habe gedacht, dass du die Funktionsweise von __set() falsch verstanden hast. Das ging mir beim ersten Versuch seinerzeit auch so.

kann man mit der Interzeptor-Methode __set() auf irgend eine weise Werte in ein existierendes numerisches Array Property der Klasse Foobar einfügen?

Das war dein erster Satz, und nein, man kann mit __set() nicht auf Elemente eines Array zugreifen, weil Arrays kein __set() haben. Man kann damit nur Schreibzugriffe auf nicht vorhandene Eigenschaften eines Objektes abfangen. Ein Zugriff auf Elemente eines Arrays ist aber keine solche Operationen.

Ein Array ist ein komplexer Typ, bestehend einerseits aus dem Array selbst, als Verwaltungsstruktur für die Elemente und andererseits aus den Elementen. Schreib-/Lesezugriffe auf Eigenschaften eines Objektes (oder Variablen allgmein), die ein Array sind, greifen nur auf das Array selbst zu, nicht jedoch auf dessen Elemente. Das geht auch mit __get()/__set() nicht anders. Man kann also mit __set() nur ein ganzes Array hinzufügen, nicht aber auf dessen Elemente zugreifen. Das wäre nämlich ein Lesezugriff auf das Array mit anschließender Operation auf den Elementen.

Oder als Code formuliert, mit einfacher Variable statt Objekt-Eigenschaft, weil es dasselbe Prinzip ist:

// Schreibzugriff auf $foo, legt ein Array an,
// als Voraussetzung für die nachfolgende Operation
$foo = [];

// zuerst erfolgt ein Lesezugriff auf $foo,
// anschließend Zugriff auf Element mit Index 42,
// in dem Fall eine Schreiboperation
$foo[42] = 'bar';

// zuerst erfolgt wieder ein Lesezugriff auf $foo,
// anschließend Zugriff auf Element mit Index 42,
// in dem Fall eine Leseoperation
echo $foo[42];

Wenn du hingegen ein Array privat verwalten möchtest, und alle Zugriffe kontrolliert werden sollen, wäre das eher über die Implementation des Interfaces ArrayAccess zu erledigen.

Ich möht gerne Wissen woran es hakt, bezogen auf deine Interpretation meiner Frage.

Das Beispiel machte etwas anderes als deine erste Frage war. Es setzte eine Eigenschaft, wenn deren Name 'array' war. Das war jedenfalls kein Array-Zugriff.

Anschließend fragtest du

und das sowas machen?

$fb = new Foobar;
$fb->tok[ $i ] = [ 'fu' => 'baz' ];

Damit greifst du lesend auf eine Eigenschaft namens tok zu. Gesetzt hast du oben aber eine Eigenschaft namens 'array'. Weiter gings es mit:

[...] jedoch habe ich keine Ahnung, wie ich Werte mit __set() in ein existierendes numerisches Array mit Index rein bringen kann, wie ich im Anwendungsbeispiel erläutert habe.

Wieder das Verständnisproblem deinerseits. Mit __set() geht sowas nicht, weil der Zugriff auf das Array ein Lesezugriff ist, also __get() oder direkt, wenn die Eigenschaft schon existiert und public ist. Das "mit Index rein bringen" findet dann im Array statt, nicht mehr im Objekt.


Deine Lösung, die du nun präsentierst, hat nur noch was mit dem Schreiben ganzer Arrays zu tun, nicht jedoch mit den im Ausgangsposting erwähnten Zugriffen auf die Elemente, was Schreiben und Lesen beinhalten würde. Es wäre vermutlich verständlicher gewesen, wenn du geschrieben hättest, was du eigentlich möchtest, und nicht nach Details zu etwas fragst, das du für die Lösung gehalten hast. Zudem kam da noch dein Verständnisproblem mit der richtigen Verwendung der Technik hinzu.

Deine jetzige Implementation von __set() macht etwas sehr unerwartetes. Es sieht aus, als ob du einer Eigenschaft Werte zuweist. In Wirklichkeit hängst du aber diese Werte an ein bestehendes Array an. Schon die Verwendung magischer Methoden ist etwas, das eine besondere Aufmerksamkeit beim Code-Leser benötigt, um zu verstehen, warum da keine Eigenschaften direkt verwendet werden. Und hier muss nun der Verwender wissen, dass er anscheinend die Eigenschaft immer wieder überschreiben muss, um in Wirklichkeit etwas anzuhängen. Sowas ist Aufgabe für eine Methode namens append(), nicht aber für Magie mit __set().

dedlfix.