Bonjour à tous,

J'ai trouvé il y a quelques jours une petite méthode pour afficher sur un site une barre de progression lors de l'exécution un peu longue d'un script php (ou n'importe quoi d'autre, mais je prendrais comme exemple du code php), en utilisant uniquement css. L'idée était d'éviter d'utiliser javascript (que je ne maitrise pas).


En ce qui me concerne, j'ai développé un script qui vérifie l'orthographe de textes littéraires soumis par l'utilisateur, en fonction de la taille du texte, l'exécution du script est plus ou moins longue, alors pour éviter que l'utilisateur s'impatiente le temps que sa requête soit traitée, j'affiche une barre de progression. Voici comment je m'y suis pris.

Comme on n'utilisera pas javascript, il ne sera pas possible d'effacer la barre de progression, mais il est tout à fait possible de la camoufler dans le reste du site.

(inspiré de ceci : http://www.phpbuilder.com/columns/white-eisenhamer20060912.php3 )

Du coté de la feuille de style, il va nous falloir ajouter les entrées suivante :

On part du principe que la barre fera 300px de large et 10 px de hauteur.


/*Barre de progression*/

/*Ceci concerne le texte qui sera affiché dans la barre*/
#bar_txt { 
  position: absolute;
  top: 5px;
  left: 50%;
  margin: 0px 0px 0px -150px;
  font-size: 10px;
  text-align: center;
  width: 300px;
  color: black;
  }




/*Ceci concerne la barre qui progressera*/
.bar {
  position: absolute;
  top: 5px;
  left: 50%;
  margin: 0px 0px 0px -158px;
  width: 0px;
  height: 10px;
  background-color: #4086b5;
}

/*Ceci concerne la couleur de fond derrière la barre*/
.blank {
  background-color: white;
  width: 300px;
}



Ensuite il va nous falloir deux fonction php, la première va servir à initialiser l'affichage de la barre :


function init_progress_bar () {
global $header ;

echo $header ;

echo "<div class='bar blank'></div>" ;
echo "<div id='bar_txt'>Veuillez patienter</div>" ;
flush(); ob_flush();flush(); ob_flush();
}


(notez qu'il vous faudra avoir déclaré une variable contenant l'en-tête html de la page à afficher, comme ceci par exemple : )

$header=<<<header
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Titre de la page</title>
  <link rel="stylesheet" type="text/css" href="style.css" media="screen" title="Styles de base" />
</head>
<body>
header;


Alors pour comprendre comment cela fonctionne.

Au moment où l'utilisateur va envoyer la requête, on va forcer le navigateur à afficher la page avant que celle-ci ne soit complètement chargée et générée par le script. Pour ça on utilise les fonctions flush() et ob_flush() plusieurs fois (c'est important car sinon certain navigateurs ne l'afficheront pas).

Ensuite nous avons besoin d'une seconde fonction :

function update_progress($percent) {
  // Now, output a new 'bar', forcing its width
  // to 3 times the percent, since we have
  // defined the percent bar to be at
  // 300 pixels wide.
  echo "<div class='bar' style='width: ",
    $percent * 3, "px'></div>\n";

  // Now, again, force this to be
  // immediately displayed:
  flush();ob_flush();flush();ob_flush();;flush();ob_flush();;flush();ob_flush();
}


Cette fonction va afficher la barre de progression au fur et à mesure que le script lui enverra le statut de progression (à envoyer en pourcentage entre 1 et 100). Les barres de plus en plus grandes vont s'empiler les une sur les autres donnant l'impression d'une barre qui progresse.

Il faudra donc appeler cette fonction à chaque fois que vous gagnez au moins 1% de progression pour afficher la barre.

Une fois arriver à 100%, on peut soit laisser la barre telle quelle, soit la camoufler en la couleur que l'on souhaite en affichant
<div class='bar blank'></div>
(créez une autre class dans css si vous voulez une couleur différente que le blanc)

Et il ne reste plus qu'à afficher le reste de la page.

Vous avez une barre de progression dynamique facile à faire et compatible avec tout les navigateurs modernes sans javascript d'activé.

Vous pouvez voir une démo ici : http://r22510.ovh.net/goldy/progress_bar

Notez que si la compression gzip est activée, cela ne marchera pas. Donc ça peut ne pas fonctionner sur certain hébergement mutualisés. De même, il vaut mieux désactiver l'affichage des warning sur apache, car la répétition des flush();ob_flush(); peut générer des messages d'erreur sans importance.
Bonsoir,

En somme, si on suit les conseils de Yslow et Page Speed (et donc qu'on utilise la compression gzip), ou si on s'attèle à éviter les erreurs Apache, ce procédé ne marche pas ?

En terme de ressources serveur ça donne quoi ? (en plus du travail de contrôle)

Merci
Riku Asakura a écrit :
Bonsoir,

En somme, si on suit les conseils de Yslow et Page Speed (et donc qu'on utilise la compression gzip), ou si on s'attèle à éviter les erreurs Apache, ce procédé ne marche pas ?

En terme de ressources serveur ça donne quoi ? (en plus du travail de contrôle)

Merci


Je ne l'ai pas testé à vrai dire, mais j'ai lu ici et là que gzip empêchait flush() de fonctionner correctement, et que pas mal de personne avec des hébergements mutualisés étaient emmerdés avec ça. Pour les erreurs non plus je n'ai pas testé ayant développé la fonction sur un serveur en prod, pareil, j'ai lu ici et là que flush répété plusieurs fois affichait soit une notice soit un warning.

Pour ce qui est des ressources, je n'ai pas mesuré, mais je n'ai pas constaté d'augmentation significative de la charge. Ensuite il est possible de l'alléger en mettant des paliers plus large. Moi j'ai mis 1% pour que ça fasse une belle progression bien fluide (et il est possible de réduire encore si on le souhaite), mais il est possible de mettre des paliers à 5, 10 % si on veut, et là l'impacte sur les ressources est infime.