web-dev-qa-db-fra.com

Si mon PHP Fonctions accepte-t-il un éventail d'arguments ou devrais-je demander explicitement des arguments?

Dans A PHP application Web, je travaille sur, je vois des fonctions définies à 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 sur une autre? Il semble que si les exigences du système continuent de changer, et par conséquent, le nombre d'arguments pour myfunc continuer à changer, l'approche 1 peut nécessiter beaucoup de maintenance.

37
John

Si le système change de manière si souvent que l'utilisation d'une matrice indexée est la meilleure solution, je dirais que c'est le moins de vos soucis. :-)

Dans les fonctions générales/méthodes ne devrait pas prendre trop d'arguments (5 plus ou moins 2 étant le maximum) et je dirais que vous devez vous tenir à l'aide de Named (idéalement type pointé ). (Un tableau indexé d'arguments n'a rien de sens que s'il existe une grande quantité de données facultatives - un bon exemple d'être des informations de configuration.)

Comme @pekka dit, le passage d'arguments est également susceptible d'être une douleur à documenter et donc à d'autres personnes/soi-même en mois de maintien.

update-ete ...

Incidemment, le livre mentionné OFT code complet examine de tels problèmes dans un délai de détail - c'est un grand tome qui je recommanderais fortement.

30
John Parker

Utilisation d'un tableau des params (un substitut pour ce qu'on appelle "arguments nommés" dans d'autres langues ") est génial - j'aime l'utiliser moi-même - mais cela a un très gros inconvénient: les arguments ne sont pas documentaires à l'aide de la notation phpdoc standard de cette façon, et Par conséquent, votre IDE==== ne sera pas en mesure de vous donner des indications lorsque vous tapez le nom d'une fonction ou d'une méthode.

17
Pekka

avec la première approche, vous forcez les utilisateurs de votre fonction pour fournir tous les paramètres nécessaires. La deuxième façon dont vous ne pouvez pas être sûr que vous avez tout ce dont vous avez besoin. Je préférerais la première approche.

5
user235064

Si les paramètres que vous passez peuvent être regroupés logiquement, vous pouvez penser à utiliser un objet de paramètre (refactoring, Martin Fowler, P295), de cette façon si vous devez ajouter plus de paramètres, vous pouvez simplement ajouter Plus de champs de votre classe de paramètres et il ne cassera pas les méthodes existantes.

4
Bedwyr Humphreys

Il y a des avantages et des inconvénients à chaque passage.

  • Si c'est une fonction simple qui est peu susceptible de changer, et n'a que quelques arguments, alors je les énoncerait explicitement.

  • Si la fonction a un grand nombre d'arguments, ou est susceptible de changer beaucoup à l'avenir, je passerais une gamme d'arguments avec des clés et utilisez cela. Cela devient également utile si vous avez une fonction où vous n'avez besoin que de passer certains des arguments souvent.

Un exemple de lorsque je choisirais un tableau sur des arguments, par exemple, si j'avais une fonction créée un champ de formulaire. Arguments possibles que je souhaite peut-être:

  • Taper
  • Valeur
  • classer
  • Identifiant
  • style
  • option
  • est requis

et je n'ai peut-être pas seulement besoin de passer quelques-uns d'entre eux. Par exemple, si un champ est TYPE = texte, je n'ai pas besoin d'options. Je n'ai peut-être pas toujours besoin d'une classe ou d'une valeur par défaut. De cette façon, il est plus facile de passer dans plusieurs combinaisons d'arguments sans avoir une signature de fonction avec des arguments de tonne et de passer null tout le temps. De plus, lorsque HTML 5 devient standard de plusieurs années à partir de maintenant, je souhaite peut-être ajouter des arguments supplémentaires possibles, tels que Tourner automatiquement sur ON ou OFF.

3
GSto

Je sais que c'est un ancien poste, mais je veux partager mon approche. Si les variables sont connectées logiquement dans un type, vous pouvez les regrouper dans une classe et transmettre un objet à la fonction. par exemple:

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

et appeler:

      $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.

0
Aris