Quelques petites astuces PHP

Je me suis rendu compte l’autre jour qu’il y avait foule de petites techniques PHP que j’utilisais au quotidien pour me simplifier la vie et le code, et que la plupart ne m’avait jamais été apprise à l’école.

Il ne s’agit pas forcement d’exclusivités, ni de meilleures façons de coder mais si vous pouvez en  trouver une ou deux utiles alors ce post n’aura pas servi à rien Sourire

N’hésitez pas à partager vos petites astuces dans les commentaires, je les placerai ici (si je les trouve justifiées évidemment)

Saviez-vous que, pour lire les fichiers d’un répertoire, vous pouviez utiliser directement la fonction scandir au lieu de opendir+readdir ? Scandir permet de plus un tri alphabétique ascendant ou descendant

ex : 

var_dump(scandir('mon/repertoire/'));

résultat :

 


Saviez-vous que vous pouviez récupérer le contenu d’un explode directement dans des variables avec la fonction list() ?

ex :

list($age,$prenom,$pseudo) = explode('|',25|valentin|idleman');


Saviez-vous que vous pouviez récupérer et sécuriser toutes vos variables POST et GET en une seule ligne dans un seul tableau de variables?

ex :

$_ = array_map('htmlentities',array_merge($_POST,$_GET));


Saviez-vous que vous pouviez utiliser la fonction file_get_contents au lieu de fopen+fread, fgets etc.. pour récupérer directement le contenu d’un fichier ?

nb : La fonction file() fait la même chose en vous retournant un tableau de lignes

ex :

$donnees_fichiers = file_get_contents('fichier.ext');

Ajout de Timo : La fonction file_put_contents permet quand à elle d’écrire simplement dans un fichier

file_put_contents('mon.fichier.txt','hello world');


Saviez-vous que pour les conditions simples vous pouviez utiliser les conditions ternaires au lieu d’un if/else?

ex:

$majeur = ($age>=18?true:false);

au lieu de

 

Ajout de William P : vous pouvez également faire directement:

 

Ajout de Anon  il existe aussi l’opérateur Elvis

foo = foo ?: bar;

Pourquoi Elvis ? => http://i.stack.imgur.com/hQlrp.png

Ajout de Walane : les parenthèses peuvent être placées uniquement sur la condition

($age >= 18) ? true : false;

 


Saviez vous que vous pouviez créer des variables dynamiques avec la notation $$ ?

ex :

 


Saviez vous que la fonction var_dump() était terriblement puissante avec le module xdebug activé?


Saviez vous que vous pouviez inclure automatiquement un fichier de classe simplement en l’instanciant ?

ex :

 

résultat : l’instruction require_once(‘User.php’); est implicitement incluse à votre code


Saviez-vous que vous pouviez faire appel à la méthode magique __call pour s’exécuter lorsqu’une fonction inconnue est située dans votre classe ?

ex :

 


Saviez-vous que vous pouviez utiliser la fonction glob() pour rechercher des types de chemins de fichier?

ex :

 

résultat : affichera tous les fichiers textes situés 2 répertoires en aval du fichier PHP.


Saviez-vous que echo ‘hello world’ bouffera moins de perf que echo « hello world » ?

En effet les  » interprètent les variables contenues dans la chaine quand ‘ se contente d’afficher votre texte tel quel, ce qui économise quelques perfs.


Saviez vous que vous pouviez écrire echo ‘hello’.’world’ ou echo ‘hello’,’world’ pour un même résultat?

Ajout de Nasty Shade : utiliser la virgule apporte un gain de rapidité exécution

Ajout de Thierry : Il serait bon de préciser que cette syntaxe ne fonctionne que pour echo. Echo accepte un nombre infini de paramètres et elle les affiche tous dans l’ordre où ils sont passés. De plus, echo n’étant pas véritablement une fonction mais une structure de langage, les parenthèses sont optionnelles


Saviez vous que vous pouviez utiliser les fonctions gzinflate, gzdeflate pour compresser les données que vous envoyez ou stockez ?


Saviez vous que, dans les boucles “for” vous pouviez utiliser l’expression : i%2==0 pour les délimiteur et les alternances de couleurs?

Ex :

 


Saviez vous que la fonction empty($var) retournera FALSE si $var existe et est non-vide, et dont la valeur n’est pas zéro?

if(!empty($string))

peut donc être utilisé en lieu de place de

if($string!='' && $string!=null)

 


Ajout de Elo : Vous pouvez automatiquement vous mailer toutes les erreurs de votre script en temps réel avec l’expression :


Ajout de Kevin : vous pouvez vous simplifier la vie en utilisant UNE seule instruction pour stocker du contenu sous forme compressée :
file_put_contents("compress.zlib://$filename", $content);

Ensuite, pour lire ce fichier compressé, UNE instruction également :

$content = file_get_contents("compress.zlib://$filename");

Article rédigé par Idleman

49 réflexions au sujet de « Quelques petites astuces PHP »

  1. William P

    Au lieu de $majeur = ($age>=18?true:false) ;
    $majeur = $age >= 18; merci :)

    et ceci ne fonctionne pas :
     »
    $nomVariable = “idleman”;

    $$nomVariable = “is so lazy…”

    echo $idle

    résultat : “is so lazy…”;
     »
    -> echo $idleman plutôt :)

    Répondre
    1. Idleman Auteur de l’article

      Tiens jconnaissais pas la première expression :), je savais que ce post me servirait aussi :D
      Merci pour la coquille, faut que j’arrête d’écrire mon pseudo en entier c’est trop crevant et je tiens pas d’une ligne à l’autre ^^.

      Répondre
  2. Steve

    On avait corrigé d’office.
    Vieux réflexe !

    Répondre
  3. Yosko

    L’histoire des simple et doubles quotes serait une légende urbaine.

    Je ne parviens plus à mettre la main dessus, mais j’avais lu un article très intéressant à ce propos, où l’auteur expliquait qu’après de nombreux tests, ils obtenait des performances similaires avec les deux, qu’il y a concaténation de plusieurs chaines ou nom, et qu’il y ait des variables dedans ou non.

    Répondre
    1. Idleman Auteur de l’article

      Ce n’est pas une légende urbaine :), outre le fait que ce soit logique que le non interpreté soit plus rapide, il y a un moyen simple de tester :
      http://idleman.fr/ressources/simpledouble.jpg

      Quel que soit le nombre de fois que je réessaye, les valeurs sont toujours en faveur du simple quote sur les 10 essais :)

      Répondre
      1. Julien et Nel

        De plus si je ne dis pas de bétise dans certains cas, si on utilise un truc du style un regex … il faudra bien choisir entre une double quote ou pas, car le truc ne sera pas exécuté de la même manière.

        Répondre
      2. MutoKenji

        Ce n’est pas une légende urbaine, mais la différence a énormément diminué avec les nouvelles versions de PHP.

        Répondre
      3. Bredt

        Oui, mais là tu triche !!!
        Tu as une variable $value, et c’est surement son interprétation qui prend du temps. Si tu refais le test sans variable (juste « Hello world » ou ‘Hello world’) ça donne quoi ?

        Répondre
        1. Idleman Auteur de l’article

          Effectivement, j’ai refait un test plus fairplay :), la différence est moindre :

          Répondre
      4. Yosko

        Je pense qu’il serait plus judicieux de comparer des exemples techniquement (et utilement) équivalent, comme :
        – « Hello World » et ‘Hello World’
        – « Hello « .$var et ‘Hello ‘.$var
        – « Hello $var » et ‘Hello ‘.$var

        Je crois que l’auteur de l’article que je mentionne (sans parvenir à le retrouver…) procédait comme ça.

        Répondre
        1. Idleman Auteur de l’article

          J’ai refait en suivant ces judicieux conseils, il semblerais que MutoKenji soit le plus proche de la vérité :

          Répondre
      5. Ziirish

        Salut,

        Je suis d’accord avec Yosko.

        http://nikic.github.io/2012/01/09/Disproving-the-Single-Quotes-Performance-Myth.html

        Je pense que l’explication à la différence de performances de ton exemple est due au fait que justement, dans le cas des doubles quotes tu as une variable à substituer, alors avec les simples quotes, cette variable ne sera pas interprétée.

        Pour vérifier, il faudrait faire ce test :


        echo "une chaine simple";

        echo 'une chaine simple';

        Et également :


        echo "une autre chaine ".$variable;

        echo 'une autre chaine '.$variable;

        Répondre
        1. Idleman Auteur de l’article

          Oui on m’a fait la remarque, je l’ai refait, le simple reste gagnant mais pas de beaucoup ^^

          Répondre
          1. Bob

            Par hasard, as-tu essayé d’inverser l’ordre des 2 boucles ? A savoir mettre les simple quote d’abord.
            Sur ma machine j’obtiens systématiquement un résultat en faveur de la seconde boucle:

            Ici j’ai les simple quote en premier: http://i.imgur.com/IvdXdj1.jpg

            :)

          2. Idleman Auteur de l’article

            Je vois mal comment ça pourrait influer sur le temps d’exécution, il faudrait faire un test dans deux fichiers différents pour être sur que ça ne dépende pas d’un historique d’exécution (mais j’ai la flemme ^^)

  4. le hollandais volant

    De la même façon que file_get_contents(), il y a file_put_contents(), qui est l’équivalent de fopen();fread();fclose();.

    Et pour lire du code PHP lu avec ça (si pour une raison ou une autre un « include » n’est pas permis), on peut faire eval($code) ?

    Ex :
    $code = file_get_contents('file.php');
    eval($code);

    Ça reviendra à faire comme si on avait copié-collé le contenu du fichier à l’emplacement du eval. Sans tous les problèmes de sous-dossiers ou d’includes avec des chemins relatifs à d’autres fichiers.

    Répondre
    1. Idleman Auteur de l’article

      Ah oui j’ai oublié de le mettre celui la ^^, pourtant les deux s’utilisent souvent de paires, je l’ajoute tout de suite.

      Pour l’include alternatif c’est intéressant, même si j’ai du mal à imaginer un cas ou le include/require soit inaccessible alors que eval + file_get_contents resteraient disponibles ^^.

      Sans compte que le eval est une fonction dangereuse et qu’un nécessiterait en fait un

      eval(str_replace(array(‘< ?php','?>‘,’

      Répondre
    1. Idleman Auteur de l’article

      Hé hé marrant, c’est une operation ternaire a une condition au finale, mais j’aime beaucoup la dénomination :)

      Répondre
  5. Tetsumaki

    Aucun rapport avec le sujet mais tu devrais, depuis l’interface d’administration WP, modifier functions.php et ajouter quelques lignes afin de désactiver le remplacement automatique des guillemets et compagnie car là ça pose un gros problème.
    J’avais du le faire lors de mes tests WordPress.

    Répondre
    1. Idleman Auteur de l’article

      EN fait j’écris avec windows live writter, c’est lui qui me remplace ça ^^, pas très malin mais bien pratique pour un crosoft :)

      Répondre
  6. Nasty Shade

    Saviez vous que vous pouviez écrire echo ‘hello’.’world’ ou echo ‘hello’,’world’ pour un même résultat?

    pas tout a fait, il parait qu’utiliser la virgure apporte un gain de rapidité d’éxécution

    tout comme il serait plus rapide d’utiliser ++$i que $i++

    Répondre
    1. Idleman Auteur de l’article

      Techniquement le résultat est donc le même, c’est la perf qui diffère :) (mais je chipotte), cela dit j’ai testé et approuvé :

      Répondre
  7. Walane

    Arf formate le code pitié et attention au bon usage des parenthèses si je peux me permettre.
    ($age>=18?true:false) ; -> ($age >= 18) ? true : false;

    ou tout simplement :
    return ($age >= 18); (parenthèses facultatives)

    Répondre
    1. Idleman Auteur de l’article

      J’ai installé un hightligther :), merci pour l’ajout :)

      Répondre
  8. elo

    Pas mal (sauf l’opérateur ternaire, qui est quand même d’un niveau assez bas, vu qu’il existe dans beaucoup de langages comme le JS, le Java, le VB…).

    Voici la mienne :

    set_error_handler(‘gestionErreur’);
    function gestionErreur( $errno, $errstr, $errfile, $errline, $errcontext)
    {
    mailto…
    }

    En cas d’erreur dans le code, permet de recevoir un courriel avec le contenu de l’ereur.
    Super pratique pour avoir une code 100% sans erreur dans une grosse appli.

    Répondre
    1. Idleman Auteur de l’article

      L’opérateur ternaire est méconnu du grand publique car beaucoup de profs passent outre cette structure en cours, je suis d’accord que c’est une base, mais je me dis que ça ne fait jamais de mal un petit rappelle pour rendre justice à cette élégante expression :)

      Merci pour l’ajout c’est publié :)

      Répondre
  9. Knah Tsaeb

    Saviez vous que vous pouviez écrire echo ‘hello’.’world’ ou echo ‘hello’,’world’ pour un même résultat?

    L’utilisation des virgules est plus rapide qu’avec les points. Le point sert à concacténer, la virgule sert de délimiteur.

    Répondre
  10. Thierry

    « Saviez vous que vous pouviez écrire echo ‘hello’.’world’ ou echo ‘hello’,’world’ pour un même résultat? »

    Il serait bon de préciser que cette syntaxe ne fonctionne que pour echo. Echo accepte un nombre infini de paramètres et elle les affiche tous dans l’ordre où ils sont passé. De plus, echo n’étant pas véritablement une fonction mais une structure de langage, les parenthèses sont optionnelles. C’est donc dans ce contexte bien particulier que l’on peut écrire :

    echo ‘hello’,’word’;

    En terme de performance, il est souvent dit que c’est plus rapide puisqu’il n’y a pas de concaténation avant de passer les paramètre à la fonction.

    Répondre
    1. Idleman Auteur de l’article

      C’est possible qu’akismet t’ai dégagé, il est mauvais en ce moment ya plein de commentaire qui passent à la trappe ^^.

      C’est rajouté merci beaucoup pour l’astuce :)

      Répondre
        1. Idleman Auteur de l’article

          Nonon toi tu etais bien la, ton commentaire était juste en attente de validation :), je l’ai d’ailleurs validé et ajouté merci :)

          Répondre
  11. Tonton

    Je crois qu’il y a une petite coquille :
     » récupérer et sécuriser toutes vos variables POST et GET en une seule ligne »
    $_ = array_map(‘htmlentities’,array_merge($_POST,$_FILE));

    C’est plutôt ça, non ?
    $_ = array_map(‘htmlentities’,array_merge($_POST,$_GET));

    En tout cas merci pour les astuces ;)

    Répondre
    1. Idleman Auteur de l’article

      Effectivement boulette d’inattention merci beaucoup pour le signalement c’est corrigé :)

      Répondre
  12. ptitpois

    Aurais je plus de chances de te contacter par ce biais … ?

    As tu essayé, comme astuce relation ptit pois patate, de donner signe de vie à ton ptit pois … ? C’est pratique ça évite un ptit pois tout rouge pas content qui peste contre patate car il ne sait pas si patate n a pas finit en purée , et puis aussi parce qu il a envie d avoir des nouvelles tout simplement

    t as peut être un rappel php pour ça ..

    fais attention un ptit pois peut changer de légume …

    Répondre
  13. Assura

    Dans le même goût que les variables dynamique, on peut aussi appeler des fonctions dynamiquement :

    class Person{
    private $name;
    private $gender;

    public function Personne($data){
    foreach( $data as $key => $value ){
    $method = ‘set’.ucfirst($key);
    if( method_exists($this,$method) ) $this->$method($value);
    }
    }

    public function setName($name){
    $this->name = $name;
    }

    public function setGender($gender){
    $this->gender = $gender;
    }
    }

    $person = new Person( array(
    ‘name’ => ‘Assura’,
    ‘gender’ => ‘M’,
    ));

    Répondre
  14. JeromeJ

    Utiliser i%2==0 pour alterner les couleurs n’est pas trop correcte ceci dit :D

    Faut pas oublier qu’il ne faut, théoriquement, jamais mélanger contenu et style.

    Ça devrait donc être fait en CSS plutôt.

    Soit, la bonne vieille méthode: En gardant le même code que ton exemple, au lieu d’alterner directement entre différentes couleurs, alterner entre différents noms de classe et laisser le CSS définir la couleur propre à chaque classe.

    Soit, la nouvelle méthode CSS3: utiliser le sélecteur #monTableau:nth-child(2n) pour définir la couleur des rangés paires et #monTableau:nth-child(2n+1) pour définir la couleur des rangés impaires.

    Sinon, ràv, pour faire mon beau gros troll :

    Le premier astuce PHP que je donnerais serait : N’utilisez pas PHP.
    « Life is short. (You need Python) » http://sebsauvage.net/python/

    Ah il serait content sebsauvage de savoir que j’utilise ses pages pour troller :x c’est mal :)

    Il y a quelques astuces que j’ignorais ceci dit, comme l’opérateur elvis par exemple.

    J’ai entendu dire qu’__autoload était très lourd par contre (et par conséquent à éviter; j’ai plus le lien sous la main par contre désolé, une recherche s’impose).

    Petit astuce supplémentaire: Pour for, et vu que tout bon programmeur est censé savoir qu’il ne faut pas utiliser directement count dans for car PHP s’amuse alors à recalculer la taille du tableau à chaque fois (comme ici: for($i = 0; $i < count($myArray); $i++)), au lieu de devoir enregistrer count($myArray) dans une autre variable sur la ligne qui précède le for, vous pouvez également passez plusieurs variables d'initiations à la boucle for (peu le savent), comme ceci:

    for($i = 0, $count = count($myArray); $i < $count; $i++)

    Enfin, si l'ordre d'itération allant de 0 au dernier élément importe peu, vous pouvez utiliser cette syntaxe :

    $i = count($myArray);
    while(–$i){
    # …
    }

    (Enfin, en troll qui se respecte, je m'en vais tester ta config php/mysql/etc et vérifier si tes messages savent stocker des caractères UTF-8 sur 4 bits (mon site pas encore, faut que je change de serveur :p): UNAMUSED FACE:

    Répondre
    1. JeromeJ

      Aha, réponse à ma question finale : non :p

      (UNAMUSED FACE est un caractère UTF-8 encodé sur 4 bytes, son bytecode est U+1F612)

      Pour faire court, pour résoudre le prob faut avoir MySQL > 5.3, utiliser l’encodage utf8mb4_unicode_ci et ne pas oublier de faire la requête SET NAMES utf8mb4 avant tout autres requêtes.

      Je vous laisse aussi un lien vers mon brouillon très moche sur l’unicode et l’utf-8 traitant de quelques uns des problèmes que j’ai rencontré en faisant la conversion. http://www.olissea.com/doc/?artId=23

      Répondre
    2. JeromeJ

      Sorry, pour le triple post, la prochaine je me relirais promis ;)

      Dans mon premier message, dans mon dernier astuce j’ai oublier un moins (à moins qu’il ne s’affiche pas). Il s’agit de :

      $i = count($myArray);
      while(–$i) {
      # …
      }

      Et pour être plus clair quant à mon second message : J’ai tenté de rajouter un caractère à la fin de mon premier message mais, comme je le craignais, celui-ci n’a (manifestement) pas pu être stocké correctement par mysql, du coup il a tronqué la fin de mon message :O
      Pour voir le coupable, il est ici : https://duckduckgo.com/?q=UNAMUSED+FACE+unicode

      Répondre
  15. Léo Maradan

    Pour l’autoloading des classes, il y a encore un problème. Si on utilise directement la fonction magique __autoload, on écrase celle-ci si une lib l’utilise aussi

    le mieux est de faire

    (php >= 5.3)
    spl_autoload_register(function ($class_name ) {
    include_once $class_name . '.php';
    });

    (php < 5.3)
    function mon_autoloader($class_name ) {
    include_once $class_name . '.php';
    }

    spl_autoload_register('mon_autoloader');

    Avec sp_autoload_register, on « empile » les autoloader. Il faut encore vérifier si le fichier existe, sinon il y aura des erreurs :)

    Répondre
    1. thib3113

      Le _autoload est pratique, sauf si vous avez une class qui en appelle d’autres, car l’_autoload va appeller toutes les class d’un coup, j’avais eu ce problème avec smarty :)

      Répondre
  16. Dodutils

    Attention au file_get_contents() qui par nature charge l’intégralité du fichier en mémoire et donc…peut blinder la mémoire allouée à PHP donc en fonction du besoin, sur les gros fichiers, un bon vieux fread() ligne à ligne sera peut-être plus efficace.

    Répondre
    1. fras

      à vérifier, fread() n’ouvre pas le fichier entier ?
      pratique aussi file(); qui ouvre le fichier dans un tableau avec une ligne par entrée.

      Pour les include, il est préférable d’utiliser require_once() et la variable magique __FILE__ qui donne le chemin absolu du fichier dans lequel il se trouve, qu’il soit inclus dans un autre fichier ou pas.
      du coup plus de problème de chemin relatif.

      pour les simple ou double quote ce n’est pas qu’une question de temps d’exécution, c’est aussi plus pratique pour la présentation.
      echo « une chaine $var »; vs echo ‘une chaine ‘.$var;
      je trouve la seconde plus lisible, surtout avec la colorisation syntaxique.

      Répondre
  17. brady

    une petite coquille il me semble
    sur la partie
     »
    if(empty($string))

    peut donc être utilisé en lieu de place de

    if($string!= » && $string!=null) »

    C’est pas plutôt if(!empty($string)) l’équivalent de if($string!= » && $string!=null) ? ^^

    Merci pour ce billet en tout cas ;)

    Répondre
  18. dot.matrix

    c’est if(!empty($string)) qui peut être utilisé en lieu de place de if($string!= » && $string!=null)
    avec le ! ;)

    super blog :)

    Répondre
    1. Idleman Auteur de l’article

      Effectivement petite coquille merci :)

      Répondre
  19. 4urny

    Salut,

    merci pour les astuces, pour les variables dynamiques j’ai essayé mais il faut rappeler la variable en faisant
    "$maVar ${$maVar}" selon la doc
    et je me demande si pour une classe il ya un procédé similaire

    Répondre

Laisser un commentaire

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

Xo ^_^ :siffle: :p :-( :evil: oO :) T_T <3 :D more »