Snippet #18 ~ PHP: les opérateurs ternaires

Petite piqure de rappel, les barbons du code m’en voudront de sortir quelque chose d’aussi évident mais certains d’entres vous pourraient se coucher moins bête Sourire (et si au passage certains de mes collègues pouvaient en prendre de la graine… *sifflote* )

Saviez vous que vous pouviez résumer ceci :

$userSex = 'H';

if($userSex=='H'){
	echo 'Bonjour monsieur!';
}else{
	echo 'Bonjour mademoiselle!';
}

a cela :

$userSex = 'H';
echo 'Bonjour '.($userSex =='H'?'monsieur':'mademoiselle').' !';

Il s’agit d’une opération ternaire, outre le fait que c’est beaucoup plus rapide à écrire, cela économise des performances sur PHP.

La condition se trouve avant le “?” la conséquence (si la condition est validée) se trouve derrière le “?” et enfin le “else” signifiant “dans les autres cas” se situe après le “:”

A noter que ce type d’opération existe dans de nombreux langages et non seulement dans PHP, renseignez vous Sourire

23 réactions au sujet de « Snippet #18 ~ PHP: les opérateurs ternaires »

  1. Tontof Réponse

    Une petite remarque concernant les performances car l’utilisation de l’opérateur ternaire peut fortement ralentir en fonction de la variable à copier (genre un gros tableau) :

    http://fabien.potencier.org/article/48/the-php-ternary-operator-fast-or-not
    http://www.ehow.com/info_12215582_php-ternary-performance.html

    Ternary Performance

    Because PHP uses the copy-on-write technique, expressions such as an else-if statement do not repeatedly copy values when executed. A ternary operator, on the other hand, does. When performing a small number of operations, such as a single operation or a small loop, the performance difference between an else-if statement and a ternary statement is negligible. However, when operations continue to grow over large amounts of iterations, the ternary operator is shown to run much slower than a simple else-if statement.

  2. bajazet Réponse

    Et ça marche dans beaucoup de langages, Java, C++ … ma vie a changé quand j’ai découvert ce test 🙂
    Je l’utilise beaucoup pour donner des valeurs par défaut, vérifier les != NULL …

    • Idleman Auteur ArticleRéponse

      Je pense qu’il existe très peu de langages nouvelles génération ne comprenant pas ce type d’expression, même C# permet de faire ça XD

  3. Yosko Réponse

    Je regrette juste une chose, qu’il ne soit pas possible de se passer du else. Enfin, tu me diras, c’est pas beaucoup plus couteux en syntaxe complète, mais bon…

    if($userSex=='H') echo 'Bonjour monsieur!';

    Par contre, il est intéressant de savoir qu’à l’inverse et depuis peu, la partie centrale est facultative. Les codes ci-dessus et ci-dessous sont donc équivalent :

    echo 'Bonjour '.(!($userSex =='H')?:'monsieur').' !';

    • Idleman Auteur ArticleRéponse

      Oui, c’est vrai que c’est un manque, j’ignorais qu’on pouvais se passer de la partie centrale, ça permet de combler la carence en inversant l’expression, merci pour l’info :p

      (en revanche tu aurais pu gagner quelques caractères et un peu de lisibilité en faisant $userSex !=’H’ au lieu de !($userSex ==’H’) mais c’est un détail)

    • Yosko Réponse

      EDIT : je viens de tester, et ça ne marche pas si bien que ça dans un ECHO.
      Après relecture de la doc si on fait (expr1?:expr3) et que expr1 est VRAI, alors VRAI est retourné.

      De ce fait dans mon exemple, ça donnerait “Bonjour 1!”. 😀

      PS : bien vu pour la simplification ^^

  4. Identitools Réponse

    La partie de moi qui est restée bloquée dans la rigueur de xHTML te répond :

    <br />

    Mais l’autre partie de moi qui s’est adaptée depuis des mois au HTML5 à envie d’ajouter que ce n’est pas une obligation.

    • Idleman Auteur ArticleRéponse

      Les
      sont ajoutés automatiquement par WordPress et n’ont rien à faire dans les snippets 🙂 tu m’as pris pour un lapin de six semaines ou quoi ^^ bien sûr que je ferme mes balises :p.

      • Yosko Réponse

        Ouais, les editeurs WYSIWYG des CMS type WP et leur gestion des retours à la ligne interfèrent souvent avec la mise en forme du code en javascript.

        J’ai eu le même souci avec BlogoText récemment.

        • Idleman Auteur ArticleRéponse

          C’est une véritable horreur ^^, d’autant qu’ils pourraient au moins ajouter des balises valides W3C 😀

          • Yosko

            Parce que je croyais que ta remarques sur les balises valides concernait le de notre cas présent.
            Mais j’imagine, à la vue de ta réponse, qu’elle était plus générale. ^^

          • Idleman Auteur Article

            Je parlais des vilains
            que wordpress a ajouté sans vergogne sur mon snippet, il aurais au moins pu les fermer comme me l’a si justement signalé identitools 🙂

  5. Knah Tsaeb Réponse

    Tant que l’on est dans les optimisations echo (qui n’est pas une function) est plus rapide avec des virgules qu’avec des points.

    echo 'blabla',$maVarviable,'blabla',maFunction(),'blabla';

    Mis bout à bout ça aide à faire des applis légères et peu couteuse.

    • Idleman Auteur ArticleRéponse

      J’ai toujours entendu dire que c’était a perfs égales entre les virgules et les . décidément voila un poste instructif ^^

      • Knah Tsaeb Réponse

        Perf égal oui et non, fait un benchmark sur 10 boucle et je suis sûr que cela seras équivalent. Après faut voir ces “petites” optimisations sur un projet à fort trafic, ou sur du tout petit matos genre homeserver, DockStar, Nas… De toute façon si sur 1000 boucle il y a une différence, il faut privilégié la plus rapide. Question de bonne pratique.

        Après 6 ans à faire du webDev cela fait 15 jours seulement que j’ai appris qu’un include (et dérivé) s’écrit sans parenthèse.
        Mauvais code

        include ('test.inc.php');

        Bon code

        include 'test.inc.php';

        • Idleman Auteur ArticleRéponse

          En ce qui concerne la virgule, si l’on se fie a la référence en la matière (http://www.phpbench.com/) elle est bien plus couteuse que le . sur un echo.

          Pour ce qui est de l’include, je l’ignorais merci pour le tuyau 🙂

          • Knah Tsaeb

            Dans le cas de http://www.phpbench.com, oui leur bench est plus rapide avec des chaînes de caractères.

            echo 'aaaaaaa'.'aaaaaaa'.'aaaaaaa'.'aaaaaaa' est plus rapide que echo 'aaaaaaa','aaaaaaa','aaaaaaa','aaaaaaa'

            Mais qui écrirais ça ? Pas moi en tous cas. Si tu fait le même test mais avec une variable, ce n’est plus le même résultat.

            echo 'aaaaaaa'.$maVariable.'aaaaaaa'.'aaaaaaa' est moins rapide que echo 'aaaaaaa',$maVariable,'aaaaaaa','aaaaaaa'


            <?php
            $t = microtime(true);
            while($i < 1000) {

            echo 'aaaaaaa',$i,'aaaaaaa','aaaaaaa';

            ++$i;
            }
            $tmp = microtime(true) - $t;
            echo '';
            echo 'virgule => ',round($tmp,6),'';

            $t = $i = $tmp;
            $t = microtime(true);
            while($i < 1000) {

            echo 'aaaaaaa'.$i.'aaaaaaa'.'aaaaaaa';

            ++$i;
            }
            $tmp = microtime(true) - $t;
            echo '';
            echo 'point => '.round($tmp,6);

            J’obtient virgule => 0.000564 et point => 0.000921

  6. pofpof Réponse

    Oui,
    mais ça rend le code peut lisible

    de plus, c’est quoi ces (et non au passage) en fin de ligne ???

    Pour faire court, sans perdre en lisibilité, les accolades auraient pu être supprimées…

    • Idleman Auteur ArticleRéponse

      Comme dis plus haut dans les commentaires ,les br sont ajoutés automatiquement par wordpress (et il semblerais qu’il ne respecte pas les normes xhtml) 🙂

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.