Sollten meine PHP-functionen ein Array von Argumenten akzeptieren oder sollte ich explizit Argumente anfordern?

In einer PHP-Webanwendung, an der ich arbeite, sehe ich functionen auf zwei verschiedene Arten definiert.

Ansatz 1:

function myfunc($arg1, $arg2, $arg3) 

Ansatz 2:

 // where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3) function myfunc($array_params) 

Wann sollte ich einen Ansatz gegenüber dem anderen anwenden? Es scheint, dass, wenn sich die Systemanforderungen ständig ändern und daher die Anzahl der Argumente für myfunc sich ständig ändert, Ansatz 1 viel Wartung erfordern kann.

Wenn sich das System so häufig ändert, dass die Verwendung eines indizierten Arrays die beste Lösung ist, würde ich sagen, dass dies die geringste Sorge ist. 🙂

Im Allgemeinen sollten functionen / Methoden nicht zu viele Argumente annehmen (5 plus oder minus 2 ist das Maximum) und ich würde sagen, dass Sie bei der Verwendung von benannten (und idealerweise typisierten ) Argumenten bleiben sollten. (Ein indiziertes Array von Argumenten macht nur dann wirklich Sinn, wenn es eine große Menge an optionalen Daten gibt – ein gutes Beispiel dafür sind Konfigurationsinformationen.)

Wie @Pekka sagt, ist das Übergeben einer Reihe von Argumenten auch ein Schmerz zu dokumentieren und daher für andere Leute / sich selbst in ‘n’ Monaten beizubehalten.

Update-Ette …

Übrigens untersucht das oft erwähnte Buch Code Complete solche Probleme ziemlich detailliert – es ist ein toller Wälzer, den ich sehr empfehlen kann.

Die Verwendung eines params-Arrays (ein Ersatz für sogenannte “named arguments” in anderen Sprachen) ist großartig – ich benutze es gerne selbst – aber es hat einen ziemlich großen Nachteil: Argumente sind nicht mit der üblichen phpDoc-Notation auf diese Weise zu dokumentieren, und Folglich kann Ihre IDE Ihnen keine Hinweise geben, wenn Sie den Namen einer function oder Methode eingeben.

Ich finde die Verwendung eines optionalen Arrays von Argumenten als nützlich, wenn ich einen Satz von Standardwerten in der function überschreiben möchte. Dies kann hilfreich sein, wenn Sie ein Objekt erstellen, das viele verschiedene Konfigurationsoptionen enthält oder nur ein dummer Container für Informationen ist. Dies ist etwas, was ich hauptsächlich aus der Ruby-Welt übernommen habe.

Ein Beispiel könnte sein, wenn ich einen Container für ein Video auf meiner Webseite konfigurieren möchte:

 function buildVideoPlayer($file, $options = array()) { $defaults = array( 'showAds' => true, 'allowFullScreen' = true, 'showPlaybar' = true ); $config = array_merge($defaults, $options); if ($config['showAds']) { .. } } $this->buildVideoPlayer($url, array('showAds' => false)); 

Beachten Sie, dass der Anfangswert von $ options ein leeres Array ist, daher ist es optional, dass es überhaupt verfügbar ist.

Mit dieser Methode wissen wir auch, dass $ -Optionen immer ein Array sein werden, und wir wissen, dass diese Schlüssel is_array() haben, so dass wir bei der Referenzierung des Arguments nicht ständig auf is_array() oder isset() überprüfen is_array() .

Mit dem ersten Ansatz zwingen Sie die Benutzer Ihrer function, alle benötigten Parameter bereitzustellen. Auf die zweite Art können Sie nicht sicher sein, dass Sie alles haben, was Sie brauchen. Ich würde den ersten Ansatz bevorzugen.

Es gibt Vor- und Nachteile für jeden Weg.

  • Wenn es eine einfache function ist, die sich kaum ändern wird und nur ein paar Argumente hat, würde ich sie explizit angeben.

  • Wenn die function eine große Anzahl von Argumenten hat oder sich wahrscheinlich in der Zukunft viel ändern wird, würde ich ein Array von Argumenten mit Schlüsseln übergeben und das verwenden. Dies wird auch hilfreich, wenn Sie eine function haben, bei der Sie nur einige der Argumente oft übergeben müssen.

Ein Beispiel für die Auswahl eines Arrays über Argumente wäre ein Beispiel, wenn ich eine function hätte, die ein Formularfeld erstellt. Mögliche Argumente, die ich möchte:

  • Art
  • Wert
  • class
  • ICH WÜRDE
  • Stil
  • Optionen
  • Wird benötigt

und ich muss vielleicht nur ein paar davon weitergeben. Wenn zum Beispiel ein Feld den Typ = text hat, brauche ich keine Optionen. Ich brauche vielleicht nicht immer eine class oder einen Standardwert. Auf diese Weise ist es einfacher, mehrere Kombinationen von Argumenten zu übergeben, ohne eine functionssignatur mit einer Tonne Argumente zu haben und die ganze Zeit über Null zu übergeben. Auch wenn HTML 5 in vielen Jahren zum Standard wird, möchte ich möglicherweise weitere Argumente hinzufügen, z. B. die automatische Vervollständigung aktivieren oder deaktivieren.

Wenn die Parameter, die Sie übergeben, logisch zusammen gruppiert werden können, könnten Sie über die Verwendung eines Parameterobjekts nachdenken ( Refactoring , Martin Fowler, p295). Wenn Sie weitere Parameter hinzufügen möchten, können Sie einfach weitere Felder zu Ihrer Parameterklasse hinzufügen Es wird nicht bestehende Methoden brechen.

Ich weiß, das ist ein alter Post, aber ich möchte meinen Ansatz teilen. Wenn die Variablen in einem Typ logisch verbunden sind, können Sie sie in einer class gruppieren und ein Objekt an die function übergeben. beispielsweise:

  class user{ public $id; public $name; public $address; ... } 

und Ruf an:

  $user = new user(); $user->id = ... ... callFunctions($user); 

Wenn ein neuer Parameter benötigt wird, können Sie ihn einfach in die class einfügen und die functionssignatur muss nicht geändert werden.