Mes fonctions PHP devraient-elles accepter un tableau d'arguments ou devrais-je demander explicitement des arguments?
Dans une application web PHP sur laquelle je travaille, je vois des fonctions définies de deux manières possibles.
Approche 1:
function myfunc($arg1, $arg2, $arg3)
Approche 2:
// where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3)
function myfunc($array_params)
Quand devrais-je utiliser une approche plutôt qu'une autre? Il semble que si les exigences du système continuent de changer, et donc le nombre d'arguments pour myfunc continuent de changer, l'approche 1 peut nécessiter beaucoup de maintenance.
7 réponses
Si le système change si souvent que l'utilisation d'un tableau indexé est la meilleure solution, je dirais que c'est le moindre de vos soucis. :-)
En général, les fonctions / méthodes ne devraient pas prendre trop d'arguments (5 plus ou moins 2 étant le maximum) et je dirais que vous devriez vous en tenir à l'utilisation des arguments nommés (et idéalement Type hinted). (Un tableau indexé d'arguments n'a vraiment de sens que s'il y a une grande quantité de données optionnelles - un bon exemple étant la configuration information.)
Comme le dit @Pekka, passer un tableau d'arguments est également susceptible d'être une douleur à documenter et donc pour d'autres personnes/vous-même dans 'n' mois à maintenir.
Mise à Jour-ette...
Incidemment, le livre souvent mentionnéCode complet examine ces questions dans un peu de détail-c'est un grand tome que je recommanderais fortement.
Utiliser un tableau params (un substitut pour ce qu'on appelle des "arguments nommés" dans d'autres langages") est génial - j'aime l'utiliser moi - même-mais il a un gros inconvénient: les Arguments ne sont pas documentables en utilisant la notation PHPDoc standard de cette façon, et par conséquent, votre IDE ne sera pas en mesure de vous donner des
Je trouve que l'utilisation d'un tableauoptionnel d'arguments est utile lorsque je veux remplacer un ensemble de valeurs par défaut dans la fonction. Il peut être utile lors de la construction d'un objet qui a beaucoup d'options de configuration différentes ou est juste un conteneur muet pour l'information. C'est quelque chose que j'ai ramassé principalement dans le monde de Ruby.
, par exemple si je veux configurer un conteneur pour une vidéo dans ma page web:
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));
Notez que la valeur initiale de $options est vide tableau, donc le fournir du tout est facultatif.
En outre, avec cette méthode, nous savons que $options sera toujours un tableau, et nous savons que ces clés ont des valeurs par défaut, donc nous n'avons pas constamment besoin de vérifier is_array()
ou isset()
lors du référencement de l'argument.
Il y a des avantages et des inconvénients dans chaque sens.
Si c'est une fonction simple qui est peu susceptible de changer, et n'a que quelques arguments, alors je les indiquerais explicitement.
Si la fonction a un grand nombre d'arguments, ou est susceptible de changer beaucoup à l'avenir, alors je passerais un tableau d'arguments avec des clés, et l'utiliserais. Cela devient également utile si vous avez une fonction où vous avez seulement besoin de passer certains des arguments souvent.
Un par exemple, si je choisis un tableau sur les arguments, pour un exemple, si j'avais une fonction qui créé un champ de formulaire. arguments possibles que je peux vouloir:
- de Type
- Valeur
- classe
- ID
- style
- options
- is_required
Et je n'ai peut-être besoin que de passer quelques-uns de ceux-ci. par exemple, si un champ est type = text, Je n'ai pas besoin d'options. Je ne peux pas toujours avoir besoin d'une classe ou d'une valeur par défaut. De cette manière, Il est plus facile de passer dans plusieurs combinaisons d'arguments, sans avoir de signature de fonction avec une tonne d'arguments et passer null tout le temps. En outre, lorsque HTML 5 devient standard dans de nombreuses années, je peux ajouter des arguments supplémentaires possibles, tels que l'activation ou la désactivation de la complétion automatique.
Si les paramètres que vous transmettez peuvent être regroupés logiquement, vous pouvez penser à utiliser un objet parameter (Refactoring, Martin Fowler, p295), de cette façon si vous avez besoin d'ajouter plus de paramètres, vous pouvez simplement ajouter plus de champs à votre classe de paramètres et cela ne cassera pas les méthodes existantes.
Je sais que c'est un vieux post, mais je veux partager mon approche. Si les variables sont logiquement connectées dans un type, vous pouvez les regrouper dans une classe et en transmettre un objet à la fonction. par exemple:
class user{
public $id;
public $name;
public $address;
...
}
Et appelez:
$user = new user();
$user->id = ...
...
callFunctions($user);
Si un nouveau paramètre est nécessaire, vous pouvez simplement l'ajouter dans la classe et la signature de la fonction n'a pas besoin de changer.