Tach!
Deshalb möchte ich der Funktion foobar($object, $wichtig1, $wichtig2) gern das Instanzieren der Objekte überlassen. Mein Problem ist jetzt, dass ich mir nicht sicher bin, wie ich die Parameter zu den Konstruktoren am elegantesten übergebe.
Als Array.
Variante 1:
foobar("Klassenname", $objectparam1, $objectparam2 /* , $objectparam3, ... */, $wichtig1, $wichtig2);
Dann würde ich in foobar() alle Parameter auswerten, die letzten beiden zur Fallunterscheidung nehmen, den ersten zur Instanzierung des Objekts und alles dazwischen in der Reihenfolge als Parameter übergeben.
Dabei gefällt mir aber nicht, dass ich umständlich die Anzahl der Parameter von foobar() ermitteln und zuordnen muss und, dass die Reihenfolge der Parameter nicht flexibel ist.
Musst du nicht. func_get_args() kennst du schon. Aus dem davon gelieferten Array poppst du die letzten beiden Elemente und instantiierst dann das Objekt mit dem restlichen Array. Mehr dazu gleich.
Variante 2:
foobar("Klassenname", array("publicvar1"=>$string1, "publicvar2"=>$string2), $wichtig1, $wichtig2);
Wenn dir positionierte Parameter reichen, dann kannst du die Keys aus dem Array weglassen - jedenfalls für meinen Lösungsvorschlag.
In dem Fall würde ich die Unterscheidung ganz sicher anhand des dritten und vierten Parameters treffen können. func_get_args() und die Verarbeitung kann ich mir sparen.
Warum stehen die beiden denn hinten? Damit man etwas schwerer drauf zugreifen muss? Wie auch immer, bei Einzel-Variablen à la Variante 1 würden sie trotzdem stören und müssten mit array_shift() aus dem func_get_args()-Array entsorgt werden. (Also, nicht ganz entsorgt, du brauchst sie ja schließlich für die Unterscheidung. Aber damit schlägst du zwei Fliegen mit einer Klappe, das Entfernen aus dem Array und das Extrahieren für deine Verwendung.)
Das schöne daran ist, dass ich die Eigenschaften der Klassen direkt mit übergeben kann anstatt im Konstruktor die Zuordnung z.b.
$this->publicvar1 = $string1;
vornehmen zu müssen.
Den Satz versteht man wohl nur richtig, wenn man den Aufbau der Klassen kennt. Wenn deine Funktion das Objekt erzeugt, muss sie entweder die Parameter an den Konstruktor übergeben oder sie nach der Instantiierung setzen. Letzteres macht sich nicht gut, wenn dabei private Eigenschaften oder Berechnungen, die der Konstruktor ausführen sollte, im Spiel sind.
Ich tendiere stark zur zweiten Variante aber ich würde gern wissen ob es noch eine bessere Möglichkeit gibt.
PHP kennt zwar call_user_func(_array)(), aber damit kann man nur bestehende Funktionen, Klassen- und Objekt-Methoden aufrufen, nicht jedoch Objekte erstellen. Das geht nur mit Reflection (und eval(), aber schön geht anders).
$instance = (new ReflectionClass($klassenname))->newInstanceArgs($parameterArray);
Wie du deine Parameter ins Array bekommst, kannst du nach deinem Geschmack lösen. Bei Variante 2 (ohne Keys) gehts es direkt, bei der ersten mit zwei (Extra-)Funktionsaufrufen.
dedlfix.