• Aucun résultat trouvé

la forme multi-paramètres (la virgule) : <?php

Dans le document Cours php4 complet (Page 143-147)

Partie 3: Sérialisation et points importants

V) Conclusion: le futur

4. la forme multi-paramètres (la virgule) : &lt;?php

echo "la valeur de x est $x"; ?>

3. La forme concaténation (le point) : <?php

echo 'la valeur de x est ' . $x; ?>

4. la forme multi-paramètres (la virgule) : <?php

echo 'la valeur de x est ', $x; ?>

Quelle est la plus performante ?

Certains pourraient être tentés de dire que la forme chaîne dynamique est la plus performante, mais ce n'est malheureusement pas le cas. Observons la décomposition faite par la fonction token_get_all: Valeur Type <?php\n T_OPEN_TAG echo T_ECHO T_WHITESPACE " la T_STRING T_ENCAPSED_AND_WHITESPACE valeur T_STRING T_ENCAPSED_AND_WHITESPACE de T_STRING T_ENCAPSED_AND_WHITESPACE x T_STRING T_ENCAPSED_AND_WHITESPACE est T_STRING T_ENCAPSED_AND_WHITESPACE $x T_VARIABLE " ; \n T_WHITESPACE

Jean Michel MEULIEN - PHP- MySQL Page 144 Valeur Type

?> T_CLOSE_TAG

Vous remarquez que tous les mots et espaces de la chaîne de caractères sont séparés. Si nous décomposons maintenant le code:

Valeur Type

<?php\n T_OPEN_TAG

echo T_ECHO

T_WHITESPACE

'la valeur de x est ' T_CONSTANT_ENCAPSED_STRING

, T_WHITESPACE $x T_VARIABLE ; \n T_WHITESPACE ?> T_CLOSE_TAG

Nous constatons désormais que la chaîne de caractères est entière ce qui conduit PHP à effectuer moins de traitements.

C'est l'une des trois autres, mais laquelle ?

En fait, les formes brutes et multi-paramètres sont sémantiquement identiques, mais le code étant un peu plus long pour la forme brute, nous pouvons considérer qu'il y a une très légère différence en faveur de la forme multi-paramètres.

Comparons donc les formes concaténation et multi-paramètres.

La forme concaténation consiste à réserver de l'espace mémoire pour accueillir le résultat de la concaténation avant de l'envoyer sur le flux de sortie alors que la forme multi-pramètres envoie chaque chaîne de caractères successivement sur le flux de sortie sans allouer d'espace mémoire inutilement. On pourrait donc s'attendre à ce que la forme multi-pramètres, en plus de consommer moins de mémoire, soit plus performante, mais ce serait aller bien vite en conclusion.

En effet, un autre phénomène entre en jeu : l'envoi sur le flux de sortie. En réalité, cette opération est gourmande en ressources et de multiples appels engendrent un ralentissement non négligeable. De ce fait, la concaténation consomme plus de mémoire, mais elle est beaucoup plus performante que les multi-paramètres.

Utilisons donc systématiquement la concaténation.

Nous faisons tous une erreur grave depuis le début : enchaîner les echo dans nos scripts. Effectivement, il y a fort à parier que vos scripts ne contiennent pas qu'un seul echo et ces appels multiples engendrent le ralentissement dont nous avons parlé précédemment.

Jean Michel MEULIEN - PHP- MySQL Page 145 Alors quelle est la solution ?

La première solution qui viendrait à l'esprit serait de concaténer toutes les chaînes de caractères dans une variable globale que l'on envoie sur le flux de sortie à la fin du script, mais ce n'est pas nécessaire. En effet, le résultat peut être obtenu de façon identique en utilisant la fonction ob_start qui place les données de sortie dans un tampon et les envoie lors de l'appel à ob_end_flush ou lorsque le script se termine. Si vous reprenez vos scripts et que vous ajoutez cette fonction avant le premier echo, vous allez constater un gain de performance fort appréciable.

Mais dans ce cas, la forme multi-paramètres devient plus performante. C'est exact, et le gain est d'environ 10% par rapport à la version "concaténation".

Pour conclure correctement cette fois-ci, je vous conseille d'utiliser ob_start au début de vos scripts et d'utiliser la forme multi-paramètres de echo.

Remarque : Vous pouvez combiner ob_start avec ob_gzhandler afin de faire d'une pierre deux coups : Accélérer le temps de génération et compresser le flux de sortie pour diminuer le temps de chargement de votre page par l'utilisateur.

Require ou include ?

Pour inclure un script dans un autre script, on peut utiliser les mots clefs require ou include. Lequel doit-on utiliser ? Peut-être connaissez-vous déjà la réponse, mais je constate souvent que certains les utilisent indifféremment sans trop vraiment se poser de questions.

Petit retour en arrière.

Avant la version 4.0.2, la différence entre les deux était très importante. En effet, le mot clef require pratiquait l'inclusion du script au moment de l'analyse et non de l'exécution. Regardons le script suivant de plus près :

<?php

function affiche_index( $chemin ) { require $chemin . 'index.html'; }

echo 'début';

affiche_index('cache/'); ?>

Ce code n'affiche pas début et génère une erreur fatale indiquant l'impossibilité d'ouvrir index.html. En fait, au moment de l'analyse, PHP a tenté d'ouvrir immédiatement le fichier, mais comme le contenu de la variable $chemin n'existe pas encore, il l'a considéré comme vide. Ainsi, en utilisant le mot clef include à la place de require, PHP n'effectue cette opération qu'au moment même de son utilisation. L'avantage du require est donc la performance car cette inclusion n'est faite qu'une seule fois, même si elle est placée dans une boucle de plusieurs millions d'itérations, mais en contrepartie, vous ne pouvez pas l'utiliser si le chemin n'est pas complètement défini.

Jean Michel MEULIEN - PHP- MySQL Page 146 Le code suivant sera correct :

<?php

$chemin = 'cache/';

require $chemin . 'index.html' ?>

En effet, le contenu de $chemin est fixé au moment de l'analyse car l'affectation est une valeur constante. En fait, cette différence a disparu à la sortie de la version 4.0.2 et l'inclusion s'effectue désormais au moment de l'exécution.

Mais une petite nuance existe et elle fait toute la différence. Tandis que require génère une erreur fatale en interrompant brutalement le script, include ne fait que générer un avertissement puis poursuit l'exécution.

Remarque : En fait, PHP génère deux erreurs, la première (avertissement) indiquant que le fichier n'existe pas et la seconde (fatale ou avertissement) indiquant que l'inclusion n'a pas pu être effectuée. Il est donc recommandé dans la très grande majorité des cas d'utiliser require afin d'interrompre le script lorsqu'un fichier est nécessaire au fonctionnement de l'application et d'utiliser include uniquement dans les cas où le script inclus peut-être absent. Bien évidemment dans le cas d’include, il faut gérer le cas où le script n'existe pas.

Valeur de retour

require et include retourne la valeur entière 1 lorsqu'on les appelle, et retourne le booléen false en cas d'erreur. En fait, il n'y a que include qui peut retourner false car require arrête le script avant même de faire le retour.

Remarque : Vous pouvez utiliser le mot clef return dans le script inclus comme pour une fonction et dans ce cas, la valeur de retour de require ou de include sera modifiée en conséquence. Vous pouvez d'ailleurs retourner false pour faire croire que l'inclusion n'a pas fonctionnée correctement.

Tester l'existence ou gérer l'erreur ? On pourrait être tenté de gérer les inclusions de deux manières différentes :

En testant l'existence du fichier à inclure : <?php

if( file_exists( 'premier.txt' ) ) require 'premier.txt'; else require 'deuxième.txt';

?>

En exploitant l'optimisation du ou : <?php

@include 'premier.txt' or require 'deuxième.txt'; ?>

Jean Michel MEULIEN - PHP- MySQL Page 147 Si on compare les performances des deux solutions, on s'aperçoit que la première est bien plus performante que la seconde, ce qui n'est pas une mauvaise chose car la première solution est bien plus claire en termes de logique. L'avantage de la deuxième forme (outre sa concision), c'est sa gestion d'une valeur de retour false générée par le fichier inclus. Dans les deux solutions, j'ai bien pris soin d'utiliser include uniquement lorsqu'il était vraiment nécessaire.

Dans le document Cours php4 complet (Page 143-147)