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 :

Array
(
    [0] => .
    [1] => ..
    [2] => bar.php
    [3] => foo.txt
    [4] => somedir
)

 


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

if($age>=18){
    $majeur =true;
}else{
    $majeur =false;
}

 

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

$majeur = $age >= 18 ;

 

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 :

$nomVariable = "idleman";
$$nomVariable = "is so lazy…";
echo $idleman
//résultat : "is so lazy…";

 


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 :

function __autoload($class_name) {
    require_once $class_name . '.php';
}
$myUser = new User();

 

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 :

__call($method,$args){

    echo ‘j’ai le vague souvenir que ma méthode’.$method.’ s’est faite la malle…essaye encore (signé : ta classe)’;
}
fonction_bidon(‘coucou’);

 


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

ex :

foreach (glob("/*/*.txt") as $filename) {
echo "$filename \n";
}

 

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 :

echo '<table>';
for($i=0;$i<10;$i++){
    echo '<tr style="background-color:'.($i%2==0?'lime':'blue').'"><td>Hello</td></tr>'’;

}
echo '</table>';

 


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 :

set_error_handler(‘gestionErreur’);
function gestionErreur( $errno, $errstr, $errfile, $errline, $errcontext)
{
   //Fonction mail ici
}

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”);

50 réactions au sujet de « Quelques petites astuces PHP »

  1. William P Réponse

    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 🙂

    • Idleman Auteur ArticleRéponse

      Tiens jconnaissais pas la première expression :), je savais que ce post me servirait aussi 😀
      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 ^^.

  2. Yosko Réponse

    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.

    • Idleman Auteur ArticleRéponse

      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 🙂

      • Julien et Nel Réponse

        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.

      • Bredt Réponse

        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 ?

      • Yosko Réponse

        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.

        • Idleman Auteur ArticleRéponse

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

      • Ziirish Réponse

        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;

          • 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

            🙂

          • Idleman Auteur 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 ^^)

  3. le hollandais volant Réponse

    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.

    • Idleman Auteur ArticleRéponse

      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(‘‘,’

    • Idleman Auteur ArticleRéponse

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

  4. Tetsumaki Réponse

    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.

    • Idleman Auteur ArticleRéponse

      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 🙂

  5. Nasty Shade Réponse

    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++

    • Idleman Auteur ArticleRéponse

      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é :

  6. Walane Réponse

    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)

  7. elo Réponse

    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.

    • Idleman Auteur ArticleRéponse

      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é 🙂

  8. Knah Tsaeb Réponse

    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.

  9. Thierry Réponse

    “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.

    • Idleman Auteur ArticleRéponse

      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 🙂

  10. Tonton Réponse

    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 😉

  11. ptitpois Réponse

    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 …

  12. Assura Réponse

    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’,
    ));

  13. JeromeJ Réponse

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

    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 😡 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:

    • JeromeJ Réponse

      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

    • JeromeJ Réponse

      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

  14. Léo Maradan Réponse

    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 🙂

    • thib3113 Réponse

      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 🙂

  15. Dodutils Réponse

    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.

    • fras Réponse

      à 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.

  16. brady Réponse

    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 😉

  17. dot.matrix Réponse

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

    super blog 🙂

  18. 4urny Réponse

    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

  19. Michel Réponse

    Bonjour,
    Ce que je lis permet de connaître vos grandes capacités. Aussi, pourriez-vous m’indiquer comment faire ceci :
    J’ai les variables tels que $prenom1 $prenom2 etc jusqu’à fin de la boucle qui permettent d’enregistrer dans la base.
    Cependant je ne sais pas combien il y aura de prénoms…
    Du coup comment, dans la boucle for, faire en sorte que la variable de récup avec un mb_eregi je peux créer les variables $prenom1, $prenom2.
    J’ai essayé en faisant :
    $cpt = $i;
    $prenom = “prenom”;
    puis
    $prenom.$cpt =$result1[1];
    mais ça ne fonctionne pas.
    Merci pour votre aide.
    Michel

Répondre à MutoKenji Annuler la réponse

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.