Trois conseils pour la rédaction de conditions PHP hermétiques • WPShout

By | juillet 11, 2019

WordPress pas cher

En PHP, conditions sont le noyau de expressions conditionnelles tel que si-tatements, et de certaines autres structures de contrôle comme tandis que() boucles.

Les surprises sont bonnes dans certains domaines de la vie, mais rarement dans le développement PHP, et savoir écrire des instructions conditionnelles claires réduira considérablement les surprises dans votre code. Tout cela revient à écrire des conditions propres et précises.

Cet article définit les conditions PHP et propose ensuite trois astuces pratiques pour créer de meilleures conditions pour un code plus prévisible et moins sujet aux erreurs.

Quelles sont les conditions en PHP

Nous avons introduit PHP tandis que boucles, et des instructions conditionnelles comme siet déclarations sinon déclarations, dans notre introduction au flux de contrôle PHP. Ces structures dictent «quel code est exécuté, quand» en PHP, et elles ont quelque chose en commun:

// instruction if
si (# condition #):
// Action
fin si;

// instruction if ... elseif ... else
si (# condition #):
// Action
elseif (# condition #):
// Action
autre :
// Action
fin si;

// boucle while ()
tandis que (# condition #):
// Action
fin si;

Ce que ces structures ont en commun sont conditions: déclarations qui évaluent soit vrai ou faux, dictant ainsi ce qui se passe dans un autre code. Ces conditions occupent la #état# parties dans le code ci-dessus (qui est certainement ne pas code réel, ne l’exécutez donc pas en direct sur l’ordinateur central de la NASA).

Et saviez-vous que vous pouvez simplement écrire des conditions dans la nature, en dehors des parenthèses? C’est moins courant, mais c’est parfaitement valide en PHP:

// Une condition sauvage apparaît!
$ boolean = 2 === 3; // Ceci est évalué à false, donc la valeur de $ boolean est maintenant false

Ce qui nous permet d’utiliser nos structures de contrôle de manière plus détaillée si nous voulons:

$ first_boolean = 2 === 3; // Ceci est évalué à false, donc la valeur de $ first_boolean est maintenant false
if ($ first_boolean === true):
echo 'je n'exécuterai pas'; // C'est vrai, tu ne le feras pas
fin si;

$ second_boolean = 1 === 1; // Ceci est évalué à true, la valeur de $ second_boolean est donc true
if ($ second_boolean === true):
echo 'j'exécuterai'; // Affiche "je vais exécuter" sur la page
fin si;

Lorsque nous disons «conditions PHP» dans cet article, nous parlons de ces 1 === 1 ou 2 === 3 (ou typeof ($ var) === 'tableau' ou toute autre chose) des déclarations elles-mêmes: des déclarations qui ont une valeur de vérité définie et qui aident un autre code à décider s’il doit être exécuté.

Ainsi, «écrire de bonnes conditions» est essentiellement la même chose que «écrire de bonnes déclarations conditionnelles» ou même «écrire de bonnes conditions». si-statements », raison pour laquelle, dans cet article, nous avons tendance à utiliser ces termes de manière assez proche.

Pourquoi devons-nous nous préoccuper de la façon dont nous écrivons des instructions conditionnelles PHP?

PHP est un lâchement tapé la langue. Tu peux me donner une variable, $ var, cela pourrait être de n'importe quel type de données. Ce peut être un entier, un booléen, un float ou même un énorme tableau associatif. Et puis je peux être comme, "Oh maintenant $ var = 'Bonjour';Et tout d'un coup $ varLe type de données change instantanément en chaîne, sans même que je doive y penser.

Cool, non?

Eh bien, en quelque sorte.

La frappe en vrac rend l'écriture PHP plus facile et moins verbeuse, mais vous donne également beaucoup de liberté pour vous gâcher. C’est un peu comme une vieille voiture qui ne craint pas de ne pas porter sa ceinture de sécurité. Cela vous donne une plus grande liberté – en quelque sorte. Mais la liberté de faire quoi? Pas porter votre ceinture de sécurité?

La solution consiste à toujours vous assurer de rester bouclé. En PHP, cela signifie écrire du code qui élimine la confusion liée au typage variable et les autres sources possibles de confusion.

Cette confusion est souvent la plus préjudiciable dans les conditions PHP qui sont le moteur de votre si-tatements et autres instructions conditionnelles, tandis que et pour boucles, et ainsi de suite. Pourquoi est-ce un problème dans cet environnement? Parce que l’essentiel des conditions est qu’elles soient bien définies: elles reviennent soit vrai ou faux, opposés parfaits. Déroulez une condition et vous êtes en difficulté.

La suite de cet article contient des conseils pratiques sur la manière d'atteindre cet objectif d'écriture de conditions PHP précises qui renvoient toujours ce qu'elles sont supposées faire.

Comment écrire les conditions PHP Airtight

Les astuces ci-dessous enseignent toutes les mêmes leçons:

  1. Être spécifique. Ecrivez les conditions pour lesquelles vous testez exactement—Pas approximativement — ce que vous vous attendez à être.
  2. Ne présumez pas. Ne pas pense vous comprenez la déclaration exacte que votre condition teste: savoir vous êtes.

Gardez ces leçons à l'esprit lorsque nous examinons des exemples de code.

1. Soyez verbeux

Ecrivez la plénitude de ce que vous essayez de tester dans vos conditions PHP. Ne coupez pas les coins.

Exemple avec un conditionnel mal écrit

Si nous voulons faire quelque chose avec une variable, nous devons nous assurer que cette variable existe, non? Donc, je suppose que nous pouvons utiliser un si– déclaration pour s’assurer que nous ne parlons pas à rien.

$ give_me_a_number = 2;

// Assurons que nous avons quelque chose pour $ give_me_a_number
if ($ give_me_a_number):
$ new_number = $ give_me_a_number + 2;
echo 'Merci pour le nombre. Il plus 2 est '. $ new_number. '.'
fin si;

Le code ci-dessus fonctionnera et imprimera «Merci pour le numéro. Il plus 2 est 4. "

Mais c’est extrêmement fragile. Voyons pourquoi:

$ give_me_a_number = 0;

if ($ give_me_a_number):
$ new_number = $ give_me_a_number + 2;
echo 'Merci pour le nombre. Il plus 2 est '. $ new_number. '.'
fin si;

Le code ci-dessus n’imprimera rien.

Pourquoi pas? Parce que 0 est très similaire, dans l’esprit de PHP, à faux. Il considère les nombres supérieurs à 0 comme «vrais», raison pour laquelle le premier exemple a été exécuté. Dans ce cas, cependant, 0 est «faux» et le écho déclaration ne court même jamais.

Encore une fois, ce n’est pas parce que $ give_me_a_number n'est pas défini ou n'existe pas. Il Est-ce que existe, c’est un int avec valeur 0—Mais ce qui arrive au nombre 0 dans une condition PHP, c'est que PHP l'examine et dit: «C'est faux."

Ce n’est pas le comportement que nous voulons: notre petite phrase devrait ajouter 2 à tous les nombres, pas «tous les nombres autres que 0».

Qu'avons-nous fait de mal? Nous étions trop concis – pas assez verbeux – et cela nous a amenés à enfreindre les deux règles énumérées ci-dessus.

Je ne parlerai même pas de toutes les autres façons de casser cette affirmation, telles que:

$ give_me_a_number = new stdClass;

if ($ give_me_a_number):
$ new_number = $ give_me_a_number + 2;
echo 'Merci pour le nombre. Il plus 2 est '. $ new_number. '.'
// Temps d'erreur fatale!
fin si;

Donc, la condition PHP ci-dessus est mauvaise. Comment pouvons-nous faire mieux?

Exemple avec un conditionnel bien écrit

Prenons un peu de recul: que sommes-nous réellement demander à notre si-déclaration?

Ce que nous voulons vraiment, c'est de nous assurer que:

  1. $ give_me_a_number est défini et:
  2. $ give_me_a_number est en fait un nombre.

Ce second bit est important. Si ce n’est pas un nombre, pourquoi essayons-nous d’ajouter 2?

Voici comment nous demandons cela en PHP:

toutes les autres façons de casser cette affirmation, telles que:

if (isset ($ give_me_a_number) && is_numeric ($ give_me_a_number)):
$ new_number = $ give_me_a_number + 2;
echo 'Merci pour le nombre. Il plus 2 est '. $ new_number. '.'
fin si;

Ce si-atatement demande exactement les deux choses que nous voulons savoir: premièrement, que $ give_me_a_number est défini et non nul; et deuxièmement, que $ give_me_a_number est numérique.

Avec cette connaissance, peu importe ce que nous jetons à notre condition PHP — nombres, chaînes, nul, objets, tableaux – il fonctionnera toujours exactement comme prévu. Si vous pouvez ajouter 2 à quelque chose, le code qu’il contient s’exécutera, et si vous ne le pouvez pas, il ne le fera pas.

Nous avons fait cela avec la magie de la verbosité: énoncer tout ce que nous entendons, chose par chose, plutôt que de nous fier à des suppositions sur une chose en impliquant une autre.

En d’autres termes, travaillez toujours pour énoncer clairement et complètement tout vos attentes, pas seulement certaines d’entre elles, dans les conditions que vous écrivez.

2. Vérifiez d'abord les types de données

Comme PHP est typé de manière vague, vos conditions PHP doivent être particulièrement claires quant aux types de données avec lesquels vous prévoyez de travailler. Si vous n'écrivez pas de cette façon, de mauvaises choses peuvent arriver. Voici un exemple.

Exemple avec un conditionnel mal écrit

Si nous voulons combiner deux tableaux, nous devons nous assurer que le second tableau contient des éléments ou qu’il ne vaut pas la peine d’y ajouter des éléments. On peut obtenir le nombre d’éléments d’un tableau en utilisant compter(), donc je suppose que nous pouvons simplement écrire cela dans notre si-déclaration.

$ shopping_list = array ('oranges', 'bananes');
$ new_list = array ('fraises');

// On s'assurera que $ new_list a des éléments avant d'essayer de les combiner
if (count ($ new_list)):
$ shopping_list = array_merge ($ shopping_list, $ new_list);
fin si;

// Génial, nous sommes maintenant prêts à imprimer notre liste de courses!
foreach ($ shopping_list as $ liste_item):
echo $ list_item. '';
fin de chaque

Le code ci-dessus imprimera «fraises oranges bananes» – cela fonctionne donc, non?

Pas vraiment. Il se base sur des hypothèses, en particulier sur les types de données, et est donc extrêmement fragile:

$ shopping_list = array ('oranges', 'bananes');

// $ new_list est une chaîne vide, ce qui est un bon moyen d'indiquer une chose "vide" ... n'est-ce pas?
$ new_list = '';

// On s'assurera que $ new_list a des éléments avant d'essayer de les combiner
if (count ($ new_list)):
$ shopping_list = array_merge ($ shopping_list, $ new_list);
// Mauvaise nouvelle: ce code fonctionnera
fin si;

// Alors maintenant nous sommes prêts à imprimer notre liste de courses
foreach ($ shopping_list as $ liste_item):
echo $ list_item;
fin de chaque

// Attend rien du tout imprimé sur la page

// Attends, que s'est-il passé?
var_dump ($ shopping_list); // Ceci affiche NULL

// Euh oh

Que s'est-il passé ici? Pour ce qui a dû être ressenti comme de bonnes raisons à l'époque, compter( '' ); dans les retours PHP 1, ne pas 0 ou une erreur. Notre si-tatement va courir, et à l'intérieur nous allons essayer le travail jamais amusant de array_merge ()deux choses qui ne sont pas les deux tableaux.

Alors qu'est-ce qui se passe quand vous array_merge () un tableau avec une chaîne? Vous recevez nul. En d’autres termes, nous avons fini par détruire le tableau original avec lequel nous essayions de fusionner.

Exemple avec un conditionnel bien écrit

Voici un meilleur code:

$ shopping_list = array ('oranges', 'bananes');
$ new_list = ''; // Faisons les fous

// Obtenons-nous réellement un tableau avec plus de 0 éléments?
if (is_array ($ new_list) && count ($ new_list)> 0):
$ shopping_list = array_merge ($ shopping_list, $ new_list);
fin si;

// Génial, nous sommes maintenant prêts à imprimer notre liste de courses!
foreach ($ shopping_list as $ liste_item):
echo $ list_item. '';
fin de chaque

Le résultat de ce qui précède sera «oranges bananes» – non nul. Plus généralement, ce code sera toujours se comporter comme prévu, y compris quand $ new_list n’est pas le tableau qu’il devrait être.

Pourquoi ce code est-il meilleur? En raison de l is_array () vérifier qui ne laisse absolument rien au hasard sur le type de chose $ new_list pourrait être.

C’est aussi mieux, à mon avis, à cause de la verbose count ($ new_list)> 0 vérifier plutôt que juste count ($ new_list). Ces choses se comportent de la même manière, mais vous dites dans l’une ce que vous voulez dire – "Je veux être sûr que ce tableau a plus de 0 éléments" – et dans une autre, vous utilisez un raccourci légèrement arrogant. Ne faites pas cela dans PHP conditionnel.

3. Ne pas déconner avec une équivalence approximative

Si quelque chose équivaut à autre chose, alors cela équivaut définitivement à cela, non?

Ha! La réponse est bien sûr non, et nous, les programmeurs PHP, sommes maintenant en train de renifler discrètement dans notre Hawaiian Punch.

Observer:

$ entier = 5; // je suis le nombre entier 5.
$ string = '5'; // je suis la chaîne "5".
$ bool = $ integer == $ string; // Ceci est le test d'équivalence lâche de PHP. Ces deux choses sont-elles égales?
// $ bool est maintenant vrai

le == tests opérateur équivalence lâche: sont deux choses égales, une fois que vous ignorez leur type de données? Il y a aussi ! =, loose not-equals: deux choses sont-elles inégales, une fois que vous ignorez leur type de données?

Si cela vous semble un raisonnement flou, alors nous sommes d’accord – et cela peut conduire à toutes sortes de résultats potentiellement étranges, comme nous allons le montrer maintenant.

Exemple d'équivalence lâche (éviter)

Voici deux échecs si contrôles qui utilisent l'équivalence lâche, plus les hijinks qui en découlent.

$ entier = 5;
$ string = '00005';

if ($ integer == $ string):
echo 'Wait what'; // Ce code fonctionnera, ce qui est mauvais
echo strlen ($ string); // Imprime "5"
echo strlen ($ integer); // Imprime "1"
// Je suppose qu'ils n'étaient pas si égaux.
// Et pourquoi exécutons-nous strlen () sur un entier?
fin si;

// Peut-être qu'ils ne sont pas égaux après tout. Vérifions encore.
if ($ integer! = $ string):
echo 'Ok, bien'; // Ce code ne fonctionnera pas, ce qui est mauvais
autre :
echo 'Wait what'; // Ce code fonctionnera, ce qui est mauvais
fin si;

Exemple d'équivalence stricte (utilisation)

Voici deux conditions PHP bien améliorées:

$ entier = 5;
$ string = '00005';

if ($ integer === $ string):
echo 'Wait what'; // Ce code ne fonctionnera pas car les entiers ne sont pas des chaînes
fin si;

// Donc ils ne sont pas égaux? Faisons en sorte
if ($ integer! == $ string):
echo 'Ok, bien'; // Ce code fonctionnera, ce qui est bien
autre :
echo 'Wait what'; // Ce code ne fonctionnera pas, ce qui est bien
fin si;

Voyez-vous la différence de code réelle? C’est l’extra = dans nos conditions – de == à === et ! = à ! ==.

Comme il se trouve, un extra = fait toute la différence, car il dénote stricte équivalence: si deux choses sont identiques en valeur et type.

Je n'ai jamais trouvé de bonne raison d'utiliser l'équivalence lâche dans mon code. Au lieu de cela, écrivez le code qui obtient exactement ce que vous recherchez, type de données inclus. N'accepter aucun substitut.

Nous sommes faits, à une condition

Si vous avez une meilleure idée du fonctionnement de PHP conditionnel et de la façon dont vous écrivez hermétiquement si-tatements, tandis que() boucles, et ainsi de suite dans votre code, alors merci de votre lecture!

Sinon, vous voudrez peut-être approfondir votre lecture ou nous contacter pour plus d'informations.

Dans les deux cas, nous aimerions avoir de vos nouvelles dans les commentaires ci-dessous ou dans notre groupe Facebook.