|
|
|
|
TUTORIEL PHP |
|
|
|
Optimiser vos applications PHP |
La popularité grandissante du Web met une pression croissante sur les logiciels et le matériel utilisé pour les applications. Cet article va vous donner les tuyaux pour réduire la charge de vos serveurs, et augmenter la capacité de vos applications sans avoir à vous ruiner en mises à jour matérielles.
(30/03/2004) |
|
(fourni
par )
Optimisation
du fichier php.ini
Il est maintenant temps de se tourner vers les directives de
configuration PHP.INI, qui peuvent aussi être utilisées pour
améliorer la performance générale de vos scripts.
Je commencerai par l'option register_globals,
qui est déjà désactivée par défaut avec PHP 4.2.0. Toutefois
beaucoup de gens l'ont toujours réactivée, car sa configuration
n'a jamais été mise à jour lors de la mise à jour de leur version
PHP. Cette option pousse PHP à enregistrer un nombre potentiellement
grand de variables basées sur les entrées utilisateur et système,
tout en rendant possible certains méthodes d'assaut. Il est
conseillé de garder cette option désactivée et d'utiliser les
super-globales toutes prêtes, pour accéder aux données passées
par l'utilisateur dans les demandes POST et GET ou les cookies
de navigation.
Vous pouvez optimiser davantage la création de variables basées
sur les entrées de l'utilisateur en changeant la directive variables_order.
Elle indique quelle source d'information du client doit être
utilisée pour engendrer les super-globales, ainsi que l'ordre
dans lequel on devrait les traiter quand on construit $_REQUEST,
qui est un résultat cumulatif des contenus d'autres super-globales.
Par défaut, la valeur de cette option est ESGPC. Cela signifie
que les données venant de l'environnement système, de l'environnement
serveur et de GET/POST/COOKIE sont enregistrés dans cet ordre.
Le stockage et la création d'éléments de tableau dans les super-globales
peut prendre une grande quantité de mémoire, et aura un impact
négatif sur chaque demande. Par conséquent vous pouvez améliorer
la performance générale de votre système en réduisant le nombre
de créations de super-globales. Dans la plupart des cas, cela
signifie que vous pouvez mettre la valeur de variables_order
simplement à GPC, de façon à ce que les données passées par
l'utilisateur dans les requêtes GET/POST ou par les cookies
soient stockées dans les super-globales.
La conséquence de ce choix est une accélération de la fonction
d'analyse en entrée, et une plus petite occupation en mémoire.
Si vous avez besoin d'accéder aux paramètres système ou aux
variables d'environnement, vous pouvez les lire avec la fonction
getenv(), ce qui ne vous pénalisera
pas.
En plus des tableaux super-globaux, PHP crée aussi des variables
spéciales qui sont utilisées pour stocker les arguments qui
sont passés en ligne de commande. Dans un environnement web,
vos scripts PHP ne recevront jamais ce type d'arguments, et
donc, la création de ces variables est parfaitement inutile.
Vous pouvez donc désactiver l'option register_argc_argv,
qui est responsable de leur création : cela va accélérer vos
scripts. Gardez en tête que si vous utilisez la version CLI
de PHP, vous aurez besoin de laisser cette option activée, car
dans ce contexte, les variables seront passées en ligne de commande.
Lorsque vous analysez les données d'entrées de votre script,
PHP va automatiquement protéger les données pour éviter que
les utilisateurs n'injectent des caractères spéciaux, qui conduiraient
à des comportements inattendus de certaines parties de votre
script. Cette protection n'est pas toujours utile, car toutes
les données provenant de l'utilisateur ne conduisent pas à un
tel trou de sécurité. Il est donc plus performant de désactiver
la directive magic_quotes_gpc et
d'assurer la protection de vos données manuellement, avec la
fonction addslashes(), ou en
utilisant toute fonction adaptée à votre application : par exemple,
vous pourriez sécuriser les données qui seront transmises au
Shell avec la fonction escapeshellcmd(),
tandis que mysql_escape_string()
sera utile avec les requêtes envoyées à MySQL.
Les avantages à assurer votre propre protection sont nombreux
: tout d'abord, vous ne protégez que ce dont vous avez besoin,
et donc, vous réduisez le temps que PHP passe sur l'analyse
des données d'entrée. Vous économisez de la mémoire, car le
processus de protection va réserver deux fois plus de mémoire
que d'habitude, pour stocker la chaîne originale, et la chaîne
traitée. De plus, vous obtenez une application mieux conçue,
qui ne dépend pas de la configuration de la plate-forme sur
laquelle elle fonctionne. Elle sera capable de s'installer normalement
même sur un environnement où magic_quotes_gpc
est désactivée.
Il y a d'autres directives de configuration qui sont importantes
pour l'optimisation de votre serveur. Par défaut, chaque requête
PHP émet un entête HTTP appelé X-Powered-By,
ce qui fait perdre un peu de temps à PHP. Cet entête est totalement
inutile, et en fait, les seules personnes qui s'intéresseront
à cet entête sont celles qui chercheront à pénétrer sur votre
système en se basant sur votre configuration. Elles commencent
par connaître la version de PHP pour en exploiter de mauvaises
configurations classiques. Il est donc prudent de désactiver
la directive expose_php. Non
seulement vous allez rendre les attaques sur votre système un
peu plus difficiles, mais en plus vous économisez de la bande
passante et augmentez les performances de PHP.
En parlant d'envoi de données à vos visiteurs, il existe un
autre domaine où une configuration correcte de PHP est très
efficace. Par défaut, PHP va envoyer les données au navigateur
dès que votre script lui en envoie : cela déclenche de nombreuses
opérations d'écriture et d'envoi à travers le réseau. Le processus
se ralentit pour les grandes pages, car de nombreux appels système
seront sollicités pour envoyer tous ces petits paquets. De plus,
certains navigateurs vont rafraîchir l'affichage de la page
à chaque réception, et cela rendra la navigation de votre visiteur
plus lente et moins agréable. Pour pallier ce problème, il suffit
de mettre en buffer les données à envoyer à travers le réseau,
et de les envoyer en groupe : cela réduit le nombre de sollicitations
des sockets, et accélère le rendu chez le client.
Les buffers de sorties sont activés et contrôlés par la directive
output_buffering, qui vous permet
de spécifier la taille de mémoire utilisée par le script pour
le buffer. Idéalement, vous allez rendre ce buffer aussi gros
que la taille moyenne de vos pages. De cette façon, la majorité
de vos pages seront envoyées en une seule fois. Mais attention,
ne créez pas de buffers trop grands, car chaque instance de
PHP va réserver un tel buffer : avec un nombre croissant de
processus fonctionnant simultanément, vous risquez de consommer
toute la mémoire disponible.
Une autre solution qui va accélérer l'envoi des données à l'utilisateur
est la compression. PHP supporte la compression GZIP à la volée
avec les buffers de sortie : les données seront compressées
avec GZIP et reconnues par la majorité des navigateurs modernes.
Pour ces derniers, la compression va réduire la taille de la
page d'un ordre de grandeur. Les pages compressées sont particulièrement
utiles pour les internautes ayant une connexion lente : dans
ce cas, cela peut leur économiser beaucoup de temps de transfert,
et dans le même temps, libérer plus rapidement votre serveur
pour qu'il serve un autre client. En conséquence, vous augmentez
le nombre d'internautes que vous pouvez servir. Un autre aspect
intéressant de cette technique est la réduction du trafic sur
votre bande passante : j'ai vu des sites réduire leurs coûts
en bande passante de 40 à 50%, uniquement en utilisant la compression
à la volée.
Mieux encore, cette fonctionnalité ne requiert aucune modification
du code des scripts, et peut être activée en donnant simplement
la valeur de ob_gzhandler à
la directive output_handler,
dans le fichier php.ini. Sinon,
vous pouvez l'activer individuellement pour les hôtes virtuels
qui vous intéressent dans httpd.conf ou bien dans des dossiers
spécifiques avec les fichiers .htaccess
; enfin, vous pouvez aussi utiliser la commande ini_set()
dans les scripts qui génèrent beaucoup de volume. Soyez conscients
que la compression à la volée consomme des ressources processeur,
et vous serez témoin d'une élévation de la charge sur votre
serveur. A vous de voir si vous pouvez le tolérer. Dans la plupart
des cas, la réduction de la bande passante et des temps de chargement
plus courts l'emportent sur la charge du processeur.
Parfois, vous utiliserez PHP non seulement pour envoyer des
données, mais aussi pour en lire depuis des sources distantes
: par exemple, lorsque vous programmez un client réseau, comme
une application email, qui lit les messages sur le serveur IMAP.
Dans ces situations, il est important de se rappeler que Internet
n'est pas un moyen de stockage local, et que lire des données
peut être très lent. Vous ne souhaitez pas passer trop de temps
à attendre que la ressource distante réponde, et bloque votre
serveur. Pour éviter les attentes infinies, vous devriez utiliser
la directive default_socket_timeout,
qui vous permet de définir le nombre de secondes d'attente de
PHP avant qu'il n'abandonne la lecture des données. C'est particulièrement
vrai dans un environnement web, car le temps que votre script
attend des informations est du temps et des ressources en attente
pour le serveur : il ne peut pas servir d'autre requêtes avec
ce processus. Il lui faudra peut-être lancer d'autres processus
pour pallier à ce manque et cela ne manquera pas d'augmenter
la charge du serveur.
En plus de requêtes distantes, vous pourriez aussi travailler
avec des sockets locales, comme pour une connexion à une base
de données. Paramétrer votre connexion est très important, car
cela vous évitera des embouteillages de connexion, qui risquent
de dégrader fortement les performances, et vous conduire à des
connexions refusées et des pages en ruine. Je vous recommande
vivement d'utiliser les directives max_links
et max_persistent qui existent
dans la plupart des interfaces de bases de données pour spécifier
le nombre de connexions que PHP peut conserver ouvertes simultanément.
Par défaut, ces directives valent -1, ce qui signifie : pas
de limite. Dans la plupart des situations, ce n'est pas une
bonne idée, car PHP risque d'essayer d'ouvrir plus de connexion
que votre serveur ne peut accepter. Cette directive est particulièrement
importante pour les connexions persistantes, car cela conduit
rapidement à ce que chaque processus Apache ait une connexion
particulière à la base de données. Il est absolument critique
de s'assurer que les connexions persistantes ne consomment pas
toutes les connexions possibles sur le serveur de base de données,
car ce dernier finirait par refuser toutes les autres connexions.
Dans de nombreux cas, par exemple si vous avez un serveur mutualisé,
il est prudent de désactiver les connexions persistantes avec
la directive allow_persistent.
Cela va convertir automatiquement toutes les tentatives de création
d'une connexion persistante en une connexion classique, et cela
aidera à limiter les dégâts sur le serveur.
Les directives de configuration de PHP proposent aussi plusieurs
moyens pour limiter les opérations de PHP peut exécuter, comme
l'accès aux fichiers ou la quantité de mémoire allouée à l'interpréteur.
Ces options sont très pratiques pour un environnement partagé,
où vous devez garder les utilisateurs dans leur pré carré, et
vous assurer qu'ils n'abusent pas du système. Mais sur un serveur
dédié, où vous contrôlez la majorité du code PHP ainsi que les
utilisateurs, ces options ne font que ralentir le serveur. Pour
des raisons de performances, les directives safe_mode,
open_basedir et memory_limit
sont inutiles en environnement dédié : les vérifications supplémentaires
qu'elles imposent sont peu économiques et conduisent à une perte
de performances.
|
|
|
|
|
|