Des valeurs par défaut ... qui cachent des bugs !
function mafunction($param1,$param2='yes') { ... }
Que se passe-t-il si vous faites cet appel :
mafunction("monparam1",null);
ou bien :
mafunction("monparam1",$value2);
avec $value2 = null ?
Nous sommes souvent tenté de créer des fonctions et/ou des méthodes pour réaliser nos tâches et logique de code. C'est normal
Dans bien des cas, nous revenons sur notre code plusieurs jours/semaines/mois après pour améliorer certaines fonctionnalités ou tout bonnement en ajouter. C'est normal
Il nous arrive alors de rajouter des paramètres facultatifs (avec ces fameuses valeurs par défaut) pour ajouter une fonctionnalité tout en restant compatible avec l'existant :
/**
* Lists enabled items of specified type
*
* @param string $type type of items to return
*
* @return array of enabled items
*/
function listItems($type) {
// ...
return $items;
}
vers par exemple :
/**
* Lists items of specified type and specified status
*
* @param string $type type of items to return
* @param string $status optional status (default is 'enabled')
*
* @return array of items
*/
function listItems($type,$status = 'enabled') {
// ....
if ('enabled' === $status) {
// ...
$items = ...
} else {
// ...
$items = ...
}
return $items;
}
Puis nous appellons notre fonction par exemple comme ceci :
$items = listItems('users');
$items = listItems('users','enabled');
$items = listItems('users','disabled');
Jusque là tout va bien... enfin vous êtes sûr ? Finalement peut être pas tant que ça, en effet, que se passe-t-il si nous faisons ces appels :
$items = listItems('users',null);
$items = listItems('users',$status); // isset($status) === false
$items = listItems('users',$status); // $status = null
Et bien le deuxième paramètre étant fourni (null dans les 3 cas), la valeur par défaut ne sera pas prise en compte ! et la variable locale '$status' dans votre fonction 'listItems' aura la valeur ... null !
Vous saisissez le problème ? En fait, au lieu d'avoir la valeur 'enabled', valeur que vous vous attendez à avoir si le paramètre $status est non fournie (et par abus de langage, null - ce qui est donc faux), vous aurez la valeur null.
Il est donc nécessaire systématiquement de rajouter un test à l'intérieur de la fonction :
function listItems($type,$status = 'enabled') {
if (!$status) {
$status = 'enabled';
}
// ....
if ('enabled' === $status) {
// ...
$items = ...
} else {
// ...
$items = ...
}
return $items;
}
voir même si vous êtes parano :
function listItems($type,$status = 'enabled') {
if (!$status || !in_array($status,array('enabled','disabled'))) {
$status = 'enabled';
}
// ....
if ('enabled' === $status) {
// ...
$items = ...
} else {
// ...
$items = ...
}
return $items;
}
Vous me direz, oui mais au lieu d'utiliser une string ('enabled') on aurait pu utiliser un boolean et le problème était réglé pas besoin de cette verrue. Vous aurez raison, mais du coup pour tous les paramètres qui ont des valeurs par défaut autre que string (regardez votre code je pense qu'il y en plein ;) ) on fait comment sinon ? ;)
Alors, gare aux bugs ! L'utilisation des valeurs par défaut pour les paramètres de fonctions/méthodes, ne vous dispense pas de vérifier leur valeur !
Commentaires
Une autre bonne habitude pour éviter ce genre de problème est d'indiquer le type de l'objet attendu, lorsque l'argument est un objet :
function foo(anObject $objet = null) {
...
}
Cette méthode évite bien des problèmes sans surcharge de code dans le corps de la fonction, vu que la vérification est prise en charge par le moteur de php nativement.
Cepdendant, vu que les types de base de PHP ne sont pas "objet" (sic), pour ces derniers, ta technique est la plus appropriée, à part dans les cas des tableaux ou la mienne fonctionne également (encore une aberration de PHP :)) :
function foo(array $array = null) {
...
}