208 votes

Utilisation d'arguments par défaut dans une fonction

Je ne comprends pas bien les valeurs par défaut des fonctions PHP. Disons que j'ai une fonction comme celle-ci :

function foo($blah, $x = "some value", $y = "some other value") {
    // code here!
}

Que faire si je veux utiliser l'argument par défaut pour $x et définir un argument différent pour $y ?

J'ai expérimenté différentes méthodes et je suis de plus en plus confus. Par exemple, j'ai essayé ces deux-là :

foo("blah", null, "test");
foo("blah", "", "test");

Mais ces deux méthodes ne permettent pas d'obtenir un argument par défaut correct pour $x. J'ai également essayé de le définir par nom de variable.

foo("blah", $x, $y = "test");   

Je m'attendais vraiment à ce que quelque chose comme ça fonctionne. Mais ça ne fonctionne pas du tout comme je l'espérais. Il semble que quoi que je fasse, je vais devoir finir par saisir les arguments par défaut à chaque fois que j'invoquerai la fonction. Et je dois manquer quelque chose d'évident.

88 votes

Vous ne manquez probablement rien, ce sont les développeurs PHP qui ont probablement manqué cela.

0 votes

C'est une question intéressante. Je n'ai jamais eu besoin de le faire comme vous l'avez dit puisque je n'utilise les args par défaut que pour étendre les fonctions héritées par d'autres programmeurs lorsque je ne suis pas sûr de ce qui dépend de l'original. Je suis curieux de connaître la réponse.

3 votes

Une des meilleures questions que j'ai vues depuis longtemps ! Avez-vous essayé de ne rien faire passer ? foo("blah", , "test"); ?

208voto

drew010 Points 32825

Je propose de modifier la déclaration de la fonction comme suit pour que vous puissiez faire ce que vous voulez :

function foo($blah, $x = null, $y = null) {
    if (null === $x) {
        $x = "some value";
    }

    if (null === $y) {
        $y = "some other value";
    }

    code here!

}

De cette façon, vous pouvez faire un appel comme foo('blah', null, 'non-default y value'); et le faire fonctionner comme vous le souhaitez, où le deuxième paramètre $x obtient toujours sa valeur par défaut.

Avec cette méthode, passer une valeur nulle signifie que vous voulez la valeur par défaut d'un paramètre lorsque vous voulez remplacer la valeur par défaut d'un paramètre qui vient après lui.

Comme indiqué dans d'autres réponses,

Les paramètres par défaut ne fonctionnent que comme derniers arguments de la fonction. Si vous voulez déclarer les valeurs par défaut dans la définition de la fonction, il n'y a aucun moyen d'omettre un paramètre et de remplacer celui qui le suit.

Si j'ai une méthode qui peut accepter un nombre variable de paramètres, et des paramètres de types différents, je déclare souvent la fonction de la même manière que la réponse donnée par Ryan P.

Voici un autre exemple (qui ne répond pas à votre question, mais qui, je l'espère, sera instructif) :

public function __construct($params = null)
{
    if ($params instanceof SOMETHING) {
        // single parameter, of object type SOMETHING
    } elseif (is_string($params)) {
        // single argument given as string
    } elseif (is_array($params)) {
        // params could be an array of properties like array('x' => 'x1', 'y' => 'y1')
    } elseif (func_num_args() == 3) {
        $args = func_get_args();

        // 3 parameters passed
    } elseif (func_num_args() == 5) {
        $args = func_get_args();
        // 5 parameters passed
    } else {
        throw new \InvalidArgumentException("Could not figure out parameters!");
    }
}

0 votes

Pourquoi pas $x = isset($x) ? $x : 'valeur par défaut' ; ?

0 votes

@zloctb c'est un contrôle de nullité propre et lisible. Il semble que ce soit la préférence des développeurs. Soit $x = isset($x) ? $x : 'default value' ; ou $x = is_null($x) ? 'default value':$x ; fonctionnerait aussi bien que cette solution. Il s'agit d'un choix de préférence concernant la lisibilité et la maintenance.

10 votes

Juste pour clarifier pour les futurs lecteurs. La première solution rend évidemment impossible l'attribution d'un réel null au paramètre, car à chaque fois, il attribuerait la valeur par défaut. Même si vous aviez une autre valeur spéciale pour les cas où vous souhaitez réellement un null (par exemple, lorsque $x == "use_null", $x = null), vous ne seriez pas en mesure d'attribuer cette valeur spéciale comme valeur littérale du paramètre (dans ce cas, la chaîne "use_null"). Assurez-vous donc d'utiliser une "clé" unique, jamais désirée, pour les cas où vous voulez utiliser la valeur par défaut (et où vous voulez que null pour être une option valable)

42voto

Ryan P Points 8292

Les arguments facultatifs ne fonctionnent qu'à la fin d'un appel de fonction. Il n'y a aucun moyen de spécifier une valeur pour $y dans votre fonction sans spécifier également $x. Certains langages supportent cela via des paramètres nommés (VB/C# par exemple), mais pas PHP.

Vous pouvez émuler cela si vous utilisez un tableau associatif pour les paramètres au lieu des arguments -- c'est à dire

function foo(array $args = array()) {
    $x = !isset($args['x']) ? 'default x value' : $args['x'];
    $y = !isset($args['y']) ? 'default y value' : $args['y'];

    ...
}

Ensuite, appelez la fonction comme suit :

foo(array('y' => 'my value'));

1 votes

Votre condition devrait vraiment être isset($args['x']) comme il remplacerait actuellement une chaîne de caractères vide, un tableau vide ou un fichier de type false avec la valeur par défaut.

0 votes

@TimCooper lol Je suis allé changer en me basant sur votre premier commentaire que cela devrait être '=== null', je suis allé changer ma réponse pour utiliser isset à la place, puis je suis revenu pour voir que vous aviez changé votre commentaire aussi :D

0 votes

Ah, zut ! Je n'aime pas du tout ça... Oh et bien, on ne peut pas tout avoir. Je suppose que je vais devoir réfléchir un peu plus à l'ordre de mes arguments par défaut alors. Merci !

4voto

wescrow Points 1859

La seule façon que je connaisse de le faire est d'omettre le paramètre. La seule façon d'omettre le paramètre est de réorganiser la liste des paramètres de façon à ce que celui que vous voulez omettre se trouve après les paramètres que vous avez choisi. HAVE à mettre en place. Par exemple :

function foo($blah, $y = "some other value", $x = "some value")

Ensuite, vous pouvez appeler foo comme :

foo("blah", "test");

Cela se traduira par :

$blah = "blah";
$y = "test";
$x = "some value";

2voto

kba Points 10874

Il n'est pas possible de le faire directement, mais un petit bricolage de code permet de l'émuler.

function foo($blah, $x = false, $y = false) {
  if (!$x) $x = "some value";
  if (!$y) $y = "some other value";

  // code
}

6 votes

Cela pourrait fonctionner, mais je trouve qu'utiliser null dans ce cas pour être conceptuellement plus propre que false .

0 votes

Je complète le commentaire de TriG, false est un choix plus risqué que null car le php est un langage non strict. !$x sera vrai pour plusieurs entrées différentes, ce qui peut surprendre le programmeur : 0 , '' . Considérant qu'avec null vous pouvez utiliser !isset comme un test plus strict.

0voto

SergeS Points 4917

Dans ce cas, les objets sont préférables, car vous pouvez configurer votre objet pour qu'il contienne x et y, définir des valeurs par défaut, etc.

L'approche avec un tableau est proche de la création d'un objet ( En fait, l'objet est un ensemble de paramètres et de fonctions qui vont travailler sur l'objet, et la fonction prenant le tableau va travailler sur un ensemble de paramètres ).

Bien sûr, vous pouvez toujours utiliser des astuces pour définir null ou quelque chose comme ceci comme valeur par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X