La fonction microtime() renvoie le nombre de secondes et de microsecondes écoulées depuis le 1/1/1970.

Suivant la valeur du paramètre booléen get_as_float, la fonction renvoie un nombre décimal ou une chaîne de caractères composée de 2 sous-chaînes :

- le nombre de microsecondes
- nombre de secondes.

Exemple : microsecondes
<?php require('bib_fonctions.php'); htmlDebut('Microsecondes'); htmlInfo('La chaîne microtime'); // par défaut microtime() renvoie une chaine echo microtime(); htmlInfo('Le nombre décimal microtime (version 1)'); // le paramètre 'get_as_float' est défini à TRUE echo microtime(TRUE); htmlFin(); ?>

On a ici l'impression que microtime() "fonctionne moins bien" quand on lui transmet TRUE pour qu'elle renvoie un nombre flottant car la précision des nombres décimaux serait insuffisante pour représenter un timestamp avec une précision de 1µs. Mais c'est en réalité un peu plus compliqué...

Pour récupérer un nombre décimal à partir de la 'chaîne microtime', nous pouvons utiliser les fonctions explode() et substr() comme dans l'exemple suivant.

Exemple : microsecondes
<?php require('bib_fonctions.php'); htmlDebut('Microsecondes'); $micro = microtime(); htmlInfo('La chaîne microtime'); echo $micro; $t = explode(' ', $micro); htmlInfo('Nombre de microsecondes'); echo substr($t[0], 2); htmlInfo('Nombre de secondes'); echo $t[1]; htmlInfo('Le nombre décimal microtime (version 2)'); $nch = $t[1].substr($t[0], 1); $n = (float)$nch; echo $nch, '<br>', $n, '<br>'; printf("%.6f", $n); htmlFin(); ?>

Explications :

- quand $n est un nombre décimal, l'instruction echo $n; affiche au maximum 14 digits. C'est l'option de configuration precision fixée dans le fichier php.ini qui détermine le nombre de digits significatifs à afficher des nombres décimaux.
- La fonction printf() permet ici d'afficher $n avec 6 digits après la virgule. Cet affichage "fonctionne" toujours car le type float en PHP permet de représenter un timestamp avec une précision de 1us.
- Les nombres flottants ont une précision limitée. Pour représenter les nombres flottants, PHP utilise le format IEEE 754, ce qui donne une erreur maximale relative de l'ordre de 2^-52 = 2.22e-16 (la mantisse est codée sur 52 bits)
  Actuellement le timestamp est à peu près égal à 1570000000 secondes.
  Or 1570000000*2.22e-16 ≈ 3.5e-7s, ce qui prouve que le type float permet de coder le timestamp avec une précision de 1us.

Conclusion : on peut utiliser la fonction microtime() en lui transmettant TRUE sans perte de précision, mais il faut prendre des précautions quand on affiche le résultat.

Le comptage du temps en microsecondes peut être utilisé par exemple pour mesurer les temps d'exécution d'un script ou de ses parties ou comme base pour la génération de nombre aléatoire.

Nous allons construire un chronomètre qui permettra de mesurer les temps d'exécution de parties de script.

Exemple : chronométre
<?php require('bib_fonctions.php'); htmlDebut('Chronométre'); function chronometrer($txt = '', $precis = 5) { static $debut, $texte, $precision; // Debut du chronométrage if ($txt != '') { $texte = $txt; $precision = $precis; $debut = microtime(); return; // Fin du début } // Arrêt du chronométrage $fin = microtime(); $t = explode(' ', $debut); $debut = $t[1].substr($t[0], 1); $t = explode(' ', $fin); $fin = $t[1].substr($t[0], 1); echo '<hr>Temps (', $texte, ') : ', round(bcsub($fin, $debut, 6), $precision), '<hr>'; } // Démarre le chronomètre chronometrer('boucle 100000 itérations'); for ($i = 0, $tmp = 0; $i < 100000; $i++) { $tmp += $i; // pour avoir quelque chose à faire } chronometrer(); // Arrête le chrono // Démarre le chronomètre chronometrer('boucle 10000 itérations', 10); for ($i = 0, $tmp = 0; $i < 10000; $i++) { $tmp += $i; // pour avoir quelque chose à faire } chronometrer(); // Arrête le chrono htmlFin(); ?>

C'est la fonction chronometrer qui fait tout le travail.

    function chronometrer($txt = '', $precis = 5) {
        static $debut, $texte, $precision;

        // Debut du chronométrage
        if ($txt != '') {
            $texte = $txt;
            $precision = $precis;
            $debut = microtime();
            return;		// Fin du début
        }

        // Arrêt du chronométrage
        $fin = microtime();
    	$t = explode(' ', $debut);
        $debut = $t[1].substr($t[0], 1);
    	$t = explode(' ', $fin);
        $fin = $t[1].substr($t[0], 1);

        echo '<hr>Temps (', $texte, ') : ',
               round(bcsub($fin, $debut, 6), $precision),
               '<hr>';
    }

Si le paramètre $txt contient quelque chose, le chronomètre est initialisé.

Si le paramètre $txt est vide, nous considérons que le chronométre est arrêté. Nous récupérons la valeur du moment, transformons le moment du début et le moment de fin en chaines numériques, puis affichons le temps d'exécution en soustrayant les deux valeurs numériques et en les arrondissant à la précision voulue.

Notez :

- l'utilisation de variables statiques. Une variable statique a une portée locale uniquement, mais elle conserve sa valeur lorsque la fonction se termine. Lorsqu'on appelle la fonction chronometrer() pour la deuxième fois, les variables statiques possèdent les valeurs qu'elles avaient à la fin de la première exécution de la fonction.
- l'utilisation de la fonction bcsub() qui permet de soustraire un nombre de grande taille à un autre.

L'utilisation de bcsub() n'est ici pas nécessaire, car comme déjà expliqué, la précision des nombres flottants utilisés par PHP est suffisante pour mémoriser le nombre de secondes et de microsecondes écoulés depuis le 1/1/1970. Nous avons utiliser bcsub() juste pour vous indiquer que PHP dispose de fonctions qui permettent la manipulation de nombres de grande taille.

Ici, on a le fait le choix d'implémenter la fonction chronometrer() comme si le type float ne permettait pas de représenter un timestamp avec une précision satisfaisante.
On peut bien entendu simplifier le code de la fonction chronometrer() en transmettant le paramètre TRUE à la fonction microtime().