web-dev-qa-db-fra.com

PHP Fonction avec paramètres facultatifs

J'ai écrit une fonction PHP pouvant accepter 10 paramètres, mais seulement 2 requis. Parfois, je veux définir le huitième paramètre, mais je ne veux pas taper de chaînes vides pour chacun des paramètres jusqu'à ce que j'atteigne le huitième.

Une de mes idées était de transmettre une fonction abstraite avec un tableau de paramètres qui la transmet à la fonction réelle.

Existe-t-il un meilleur moyen de configurer la fonction afin de ne pouvoir transmettre que les paramètres souhaités?

94
user481826

Faites que la fonction prenne un paramètre: un tableau. Transmettez les paramètres réels en tant que valeurs dans le tableau.


Edit: le lien dans le commentaire de Pekka résume à peu près tout.

56
Matt Ball

Ce que j'ai fait dans ce cas est de passer un tableau, où la clé est le nom du paramètre et la valeur est la valeur.

$optional = array(
  "param" => $param1,
  "param2" => $param2
);

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}
60
Rabbott

Pour accomplir ce que vous voulez, utilisez un tableau Comme Rabbot l’a dit (même si cela peut devenir un problème pour documenter/maintenir si utilisé excessivement). Ou utilisez simplement les arguments optionnels traditionnels.

//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
  //Do stuff
}
my_func('Hi', 'World', null, null, 'Red');

Cependant, je trouve généralement que lorsque je commence à écrire une fonction/méthode avec autant d’arguments - c’est le plus souvent une odeur de code, qui peut être remaniée/abstraite en quelque chose de beaucoup plus propre.

//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
  return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');
43
Kayla Rose

NOTE: Ceci est une ancienne réponse, pour PHP 5.5 et inférieur. PHP 5.6+ supporte les arguments par défaut

Dans PHP 5.5 et inférieur, vous pouvez y parvenir en utilisant l'une des 2 méthodes suivantes:

  • en utilisant les fonctions func_num_args () et func_get_arg ();
  • en utilisant des arguments NULL;

Comment utiliser

function method_1()
{
  $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
  $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}

function method_2($arg1 = null, $arg2 = null)
{
  $arg1 = $arg1? $arg1: "default_value_for_arg1";
  $arg2 = $arg2? $arg2: "default_value_for_arg2";
}

Je préfère la deuxième méthode car elle est propre et facile à comprendre, mais vous pouvez parfois avoir besoin de la première méthode.

10
Daniel Loureiro

Dans PHP 5.6 et versions ultérieures, les listes d'arguments peuvent inclure le jeton ... pour indiquer que la fonction accepte un nombre variable d'arguments. Les arguments seront transmis à la variable donnée sous la forme d'un tableau; pour exemple:

Exemple d'utilisation de ... pour accéder à des arguments variables

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

L'exemple ci-dessus affichera:

10

Listes d'arguments de longueur variable PHP Documentation

10
Mentos1386

Vous pouvez simplement définir la valeur par défaut sur null.

<?php
function functionName($value, $value2 = null) {
// do stuff
}
9
Blake Stevenson

Je pense que vous pouvez aussi utiliser des objets comme paramètres de transport.

$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);

function theFunction($fparam){      
  return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}

Bien sûr, vous devez définir les valeurs par défaut pour "optParam8" et "optParam2" dans cette fonction. Dans le cas contraire, vous obtiendrez "Remarque: propriété non définie: stdClass :: $ optParam2"

Si vous utilisez des tableaux comme paramètres de fonction, j'aime bien cette méthode pour définir les valeurs par défaut:

function theFunction($fparam){
   $default = array(
      'opt1' => 'nothing',
      'opt2' => 1
   );
   if(is_array($fparam)){
      $fparam = array_merge($default, $fparam);
   }else{
      $fparam = $default;
   }
   //now, the default values are overwritten by these passed by $fparam
   return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}
4
psad

Si seules deux valeurs sont nécessaires pour créer l'objet avec un état valide, vous pouvez simplement supprimer tous les autres arguments facultatifs et leur fournir des paramètres (à moins que vous ne souhaitiez pas qu'ils soient modifiés au moment de l'exécution). Ensuite, il suffit d'instancier l'objet avec les deux arguments requis et de définir les autres selon les besoins via le setter.

Lectures complémentaires

2
Gordon

Je sais que c’est un vieux post, mais j’avais un problème comme celui de l’opérateur et c’est ce que j’ai trouvé.

Exemple de tableau que vous pourriez transmettre. Vous pouvez commander à nouveau si une commande particulière est requise, mais pour cette question, cela fera ce qui est demandé.

$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');

Ceci est gérable, facile à lire et les points d’extraction de données peuvent être ajoutés et supprimés à tout moment en codant, tout en évitant une réécriture massive. J'ai utilisé des clés entières pour concorder avec la question initiale de l'OP, mais les clés de chaîne pouvaient être utilisées aussi facilement. En fait, pour des raisons de lisibilité, je le conseillerais.

Collez ceci dans un fichier externe pour plus de facilité

function unknown_number_arguments($argument_set) {

    foreach ($argument_set as $key => $value) {

        # create a switch with all the cases you need. as you loop the array 
        # keys only your submitted $keys values will be found with the switch. 
        switch ($key) {
            case 1:
                # do stuff with $value
                break;
            case 2:
                # do stuff with $value;
                break;
            case 3:
                # key 3 omitted, this wont execute 
                break;
            case 5:
                # do stuff with $value;
                break;
            case 8:
                # do stuff with $value;
                break;
            default:
                # no match from the array, do error logging?
                break;
        }
    }
return;
}

mettez ceci au début si le fichier.

$argument_set = array(); 

Utilisez-les simplement pour attribuer à la donnée suivante la numérotation/nom en fonction de l’origine des données.

$argument_set[1][] = $some_variable; 

Et enfin passer le tableau

unknown_number_arguments($argument_set);
2
Chris

Si vous passez généralement la 8e valeur, vous pouvez réorganiser vos paramètres pour que ce soit la première. Il vous suffit de spécifier les paramètres jusqu'au dernier paramètre que vous souhaitez définir.

Si vous utilisez des valeurs différentes, vous avez 2 options.

L'une serait de créer un ensemble de fonctions d'encapsidation prenant différents paramètres et définissant les valeurs par défaut des autres. Ceci est utile si vous n’utilisez que quelques combinaisons, mais que vous risquez de vous salir rapidement.

L'autre option consiste à passer un tableau où les clés sont les noms des paramètres. Vous pouvez alors simplement vérifier s'il y a une valeur dans le tableau avec une clé et sinon utiliser la valeur par défaut. Mais encore une fois, cela peut devenir désordonné et ajouter beaucoup de code supplémentaire si vous avez beaucoup de paramètres.

0
Alan Geleynse