Bonjour à tous !
C'est après une longue absence que je publie cet article, pour vous donner quelques conseils d'optimisation PHP.
C'est en fait depuis que je me suis remis à mon jeu en ligne futuriste FuturaX que j'avais commencé il y a quelques années, et que je développe seul la seconde version, que je me suis rendu compte de la différence entre mon code de 2004 et mon code d'aujourd'hui, et que je me suis dit que ça valait la peine de vous faire profiter de quelques astuces...
Voici la liste des différences techniques :
- J'ai changé d'OS pour développer (Win 98 ou 2000 je sais plus, à un Linux Mandriva, mais sur un ordinateur qui ne s'est pas amélioré comme l'OS : 256Mo de RAM et processeur poussif).
- J'ai changé d'encodage : je passe du ISO-machinchouette-3 à l'UTF-8, j'avais notamment eu un problème dû à l'encodage quand j'ai tenté de passer à l'AJAX (vous ne savez pas ce que c'est ? Pas grave, je vous ferai un article là-dessus si je prends le temps ^^)...
- J'utilise désormais KDE (avec Linux, désolé pour les gnomes^^) qui permet notamment la gestion transparente du protocole FTP (entre autres), c'est-à-dire que je visualise un dossier distant, j'ouvre une image pour la modifier, je change les propriétés d'un fichier comme si j'étais en local. Cependant comme c'est légèrement plus lent (on s'en doute) et que Olympe-Network (mon génial hébergeur :P ) n'autorise pas plus de 80 utilisateurs connectés en même temps sur le FTP (sur 18000 utilisateurs), ça devenait difficile de développer directement en ligne... J'ai donc installé le serveur Apache et le reste (15 secondes chrono, vive Linux) pour pouvoir développer en local (et je me débarrasse ainsi de tout EasyPHP ou autre pseudo-serveur).
Ce que vous devez retenir, c'est (mis à part que Linux c'est bien - et compliqué) :
- L'UTF-8 C'EST BIEN C'EST BON MANGEZ-EN !! Sérieusement, c'est beaucoup plus souple, pour quelques modifications pas difficiles : changer l'encodage dans votre éditeur préféré, ajoutez l'en tête HTTP et le meta-tag dans vos pages :
<?php header('Content-type: text/html; Charset: UTF-8'); ?> (en adaptant bien sûr le content-type - type du contenu)
Et <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> (de même pour le content-type)
- Au niveau technique c'est à peu près tout, je ne préfère pas vous donner de conseils trop précis pour ce qui est de l'IDE (environnement de développement) ni de l'OS (gniark gniark ^^)
Pour ce qui est des habitudes de codage, certaines astuces vont sûrement vous intéresser / vous aider :
Manuel des fonctions
Premièrement, n'hésitez pas à ajouter le moteur de recherche du manuel PHP (RTFM qu'on vous dit !) soit en allant directement sur le site http://php.net/ et en ajoutant le moteur de recherche (ça marche sous Firefox du moins) ou bien pour vous simplifier la vie, en cliquant ici pour ajouter directement le moteur de recherche à Firefox.
Vous n'avez alors plus qu'à entrer un nom de fonction, de classe, de ce que vous voulez pour obtenir la documentation complète et les exemples !
Utilisez des classes (et vive la POO ^^)
Deuxièmement, utilisez des classes si cela est pertinent et utile dans le contexte, par exemple pour la gestion de MySQL. C'est ce que j'ai fait, et je peux ainsi centraliser la gestion des erreurs MySQL, la sécurisation des requêtes (contre les injections SQL), ou encore compter le temps mis pour effectuer une requête, le nombre de requête par page en moyenne...
Les expressions ternaires
Utilisez les expressions ternaires, qui fonctionnent de la manière suivante :
$nom = (empty($pseudo)) : 'Inconnu' ? $pseudo;
Elles permettent de remplacer les instructions IF de manière plus réduite, condensée et efficace (sous la forme condition : valeur-si-oui ? valeur-si-non).
L'URL Rewriting
L'URL Rewriting (un article viendra prochainement) permet une gestion beaucoup plus souple des URLs, une petite sécurité supplémentaire, et beaucoup de soucis en moins !L'utilisation des include_once (et require_once) permet d'éviter la double inclusion de code (librairies, configurations, etc...)
Les guillemets simples et doubles
Les guillemets simples sont à préférer aux guillemets doubles dans de nombreux cas. Ce n'est pas une réelle question de rapidité, mais plus de facilité pour vous :
Je rappelle qu'il existe deux manières d'afficher (par exemple) une chaîne de caractères :
echo "Bonjour toi !"; ou
echo 'Bonjour toi !';La différence majeure est que les guillemets doubles permettent d'inclure des variables :
echo "Bonjour "; echo $nom; echo ", ça va ?"; est similaire à
echo "Bonjour $nom, ça va ?"; et affichera "
Bonjour Camille, ça va ?" si la variable
$nom contient Camille.
Au contraire, vous serez obligés de concaténer les morceaux avec les guillemets simples :
echo "Bonjour ",$nom,", ça va ?"; Dans ce cas, les guillemets doubles sont largement préférables, car ils vous permettent de mieux écrire et visualiser vos chaînes formatées, et je vous encourage vivement à les utiliser dans le cas où vous avez des variables à inclure.
Cependant, dans le cas où par exemple vous affichez du HTML, avec de nombreux attributs pour vos balises, je pense qu'il est préférable d'utiliser les guillemets simple pour éviter d'antislasher tous les guillemets doubles du HTML (mais il faudra alors antislasher les guillemets simples). Je m'explique (vous en avez sans doute grand besoin) :
Pour afficher
<div class="volante" id="boite_volante"><bold title="Vous avez un nouveau message"><a href="messages.html" title="Afficher ces 2 nouveaux messages">2 Nouveaux Messages !</a></bold></div>, il vaut mieux écrire
echo '<div class="volante" id="boite_volante"><bold title="Vous avez
un nouveau message"><a href="messages.html" title="Afficher ces 2
nouveaux messages">2 Nouveaux Messages
!</a></bold></div>';
que
echo "<div class=\"volante\" id=\"boite_volante\"><bold title=\"Vous avez
un nouveau message\"><a href=\"messages.html\" title=\"Afficher ces 2
nouveaux messages\">2 Nouveaux Messages
!</a></bold></div>";
De même, j'utilise généralement des fonctions du type
message($message) appelées par exemple comme
message('Une erreur vient de se produire !!"); (enfin celui-ci j'aime pas trop m'en servir :P). Ici l'utilisation de guillemets simples est plus utile.
En règle générale, il vaut mieux faire comme bon vous semble, pour avoir le moins d'anti-slashs à placer dans vos chaînes de caractères.
Journalisation des évènements
Depuis la première version de mon jeu, je journalise les évènements se produisant dans le jeu, au niveau du PHP, comme par exemple, la connexion d'un joueur, chacune de ses actions (construire, attaquer, message...) ainsi que les données techniques (synchronisation de tel ou tel fichier, intrusion, etc...).
Une simple fonction gère cela :
// Enregistrement des actions
function logue($txt){
// $fic = @file_get_contents(_LOG); // Le fichier n'existe pas forcément
$txt = '['.date('d/m-H:i').'] '.$txt;
$fichier = fopen(_LOG,'a+');
fputs($fichier, "\n$txt");
fclose($fichier);
}
// Nettoyage des logs
function nettoielogs(){
unlink(_LOG);
logue('Réinitialisation du log...');
}Où _LOG contient l'adresse interne du fichier.
Ce fichier est envoyé toutes les 24H sur mon adresse mail personnelle et termine dans un dossier spécialisé.
Les raccourcis, les astuces diverses
Connaissez-vous
file_get_contents, ou
file_put_contents ?
Savez-vous chronométrer le temps d'exécution d'une page, d'une action particulière ?
Un simple appel à
microtime et une petite soustraction suffit !
Les optimisations SQL
Ca, c'est un gros chapitre ! J'ai récemment écouté quelqu'un qui comptait stocker ses templates HTML (tout le code HTML autour du contenu) dans une base de données, et qui voulait les récupérer pour chaque page. Il ne connaissait pas la fonction
include.
Mon hébergement chez Olympe m'a fait comprendre qu'il était utile - et même important - d'optimiser le volume de données transitant sur le réseau, notamment pour les requêtes SQL.
En utilisant des requêtes plus complètes, plus poussées, on peut faire transiter le strict minimum, et ainsi alléger grandement
le pauvre serveur SQL d'Olympe-Network votre propre serveur SQL.
- Tout d'abord, l'étoile (astérisque) est à proscrire des requêtes :
SELECT * FROM `utilisateurs` est mauvais pour plusieurs raisons :
- Vous récupérez TOUS les champs correpondants, même si vous n'en avez pas besoin. C'est souvent près d'1Ko de données par requête par enregistrement, soit beaucoup en 24H pour l'ensemble des enregistrements de l'ensemble de vos bases sur l'ensemble de vos pages appelées par l'ensemble de vos visiteurs... Vous suivez ? ^^
- Vous ne connaissez pas la structure de la table que vous appelez ! Généralement je préfère avoir le nom des champs que j'utilise, ça me permet de coder beaucoup plus rapidement.
- Pour compter le nombre d'enregistrements (nombre de messages, de joueurs, etc...) pensez à utiliser
SELECT COUNT(*) AS nb FROM `utilisateurs` qui renvoie pour nb le nombre d'enregistrements (non nuls).
- Vous pouvez effectuer des sélections croisées, pour cela je ne peux que vous indiquer l'excellent article sur le site du zéro
Voilà, là je suis un peu en manque d'idées, je compléterai sûrement cet article si des choses me reviennent.
J'espère que tout ceci pourra vous être utile =D
Derniers commentaires