Frage

Ich sehe diese Redewendung oft beim Lesen von PHP -Code:

public function __construct($config)
{
    if (array_key_exists('options', $config)) {
       ...
    }
    if (array_key_exists('driver_options', $config)) {
        ...
    }
}

Hier bin ich Sorgen um die Art und Weise, wie der Parameter verwendet wird. Wenn ich in Lisp wäre, würde ich es tun:

(defun ct (&key options driver_options) 
       (do-something-with-option-and-driver_option))

Aber da ich in PHP bin, hätte ich lieber einen Konstruktor, der eine Liste von Parametern aufnimmt und sie null ist, wenn es nicht erforderlich ist.

Was denkst ihr also, dass ein Array als Parameter in einem anderen Initialisierungs- oder was auch immer?

In anderem zur Beantwortung müssen Sie die Sichtweise des Benutzers der Funktion und des Designers der API berücksichtigen.

War es hilfreich?

Lösung

Persönlich mag ich diese Idiom nicht. Ich bevorzuge stattdessen eine lange Parameterliste, falls erforderlich.

Das Problem ist, dass ich die Elemente, die das Array nicht aufnehmen kann, nicht wissen kann, indem ich mich die Funktionssignatur ansehen kann. Darüber hinaus prüfen die Implementierungen fast nie, ob es keinen Schlüssel gibt, der nicht erkannt wird. Wenn ich also einen Array -Schlüssel falsch zeige, bekomme ich keine Warnung.

Eine bessere Alternative wäre ein Konfigurationsobjekt. Zumindest kann die IDE mir Hinweise auf die verfügbaren Konfigurationsobjekte liefern, und die berechneten Standardwerte für fehlende Optionen können vom Konstruktor, den Sie den Getters im Konfigurationsobjekt anzeigen, weggezogen werden. Die offensichtliche Alternative besteht darin, Setzer für die verschiedenen Konfigurationsoptionen bereitzustellen. Dies hilft jedoch nicht für die erforderlichen, für jedes keine Standardeinstellung kann bereitgestellt werden.

Andere Tipps

Ich mag das Designmuster von "Options -Arrays" sehr. Wenn PHP Pythons Argument -Expansion unterstützt, würde ich mich damit einverstanden machen, mit einer langen Parameterliste zu gehen. Aber ich finde nur foo(1, 2, 'something', true, 23, array(4), $bar); wirklich nicht lesbar sein. Ich verwende normalerweise Arrays, wenn es mehr als etwa 3 oder 4 Parameter gibt, die eingestellt werden müssen ...

Was ich vorschlagen würde, um den Konstruktor "aufzuräumen", ist eine geschützte Methode zum Zugriff auf Konfigurationsvars (vorzugsweise in einer Basisklasse):

abstract class Configurable {
    protected $options = array();
    protected $requiredOptions = array();

    public function __construct(array $options = array()) {
        $this->options = $options;
        foreach ($this->requiredOptions as $option) {
            if (!isset($this->options[$option])) {
                throw new InvalidArgumentException('Required argument [$'.$option.'] was not set');
            }
        }
    }

    protected function _getOption($key, $default = null) {
        return isset($this->options[$key]) ? $this->options[$key] : $default;
    }
}

In Ihrer Klasse können Sie dann das Array für das Erfordernisse überladen, um Dinge zu definieren, die festgelegt werden müssen

class Foo extends Configurable {
    protected $requiredOptions = array(
        'db',
        'foo',
    );

    public function __construct(array $options = array()) {
        parent::__construct($options);
        if ($this->_getOption('bar', false)) {
            //Do Something
        }
    }
}

Eine Sache. Wenn Sie dies tun, dokumentieren Sie bitte die erforderlichen Optionen. Es wird das Leben für diejenigen, die Ihnen folgen, viel einfacher machen.

Ich finde, dass die Verwendung von Arrays als Parameter hilfreich ist, wenn es viele optionale Parameter gibt. Normalerweise verwende ich ein Array_Merge, um das übergebene Array mit dem Array "Standards" zusammenzuführen. Keine Überprüfung erforderlich. Wenn Sie Parameter benötigt, können Sie Array_Diff_key verwenden, um festzustellen, ob die erforderlichen Parameter fehlen.

function params($p_array) {
    static $default_vals = array('p1'=>1, 'p2'=>null, 'p3'=>'xyz');
    static $rqd_params = array('p1'=>null, 'p3'=>null);
    // check for missing required params
    $missing_params = array_diff_key($rqd_params, $p_array);
    if ( count($missing_params)>0 ) {
       //return an error (i.e. missing fields)
       return array_keys($missing_params);
    }
    // Merge passed params and override defaults
    $p_array = array_merge($default_vals, $p_array);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top