Bonjour,

J'aimerais utiliser une progress barre qui indique la progression de l'execution d'un script php (plutôt long).

Seulement je ne sais pas comment m'y prendre, pouvez vous me conseiller ?

11 réponses


Salut,

Grafikart a fait une très bonne vidéo là-dessus :
https://www.grafikart.fr/tutoriels/jquery/progress-bar-440

cid5420
Auteur

Ok oui très bon tuto mais comment l'adapter à ce que je veux faire ? c'est à dire dans une méthode où j'ai 10 requêtes ?

Bonjour.

dans une méthode où j'ai 10 requêtes

Tu veux dire 10 requêtes SQL ?
Si c'est le cas, ça fait un peu trop dix requêtes SQL pour une seule méthode, tu devrais penser à revoir ta méthode pour diminuer le nombre de requêtes SQL qu'elle effectue.

cid5420
Auteur

J'exagere un peut mais il se trouve que je dois faire une opération un peut longue, (calcule + requete sql)

Montre nous ton script, en l'état nous ne pouvons t'aider.

cid5420
Auteur

Bon bah voila ^^

public function calcul()
    {
        $date = str_replace('-', '/', str_replace(' ', '', $_GET['date']));
        $n = 0;
        //POUR CHAQUE LIGNE PPD DU MOIS $date
        $ppd = $this->FtthPpd->lastPPDMois($date);
        foreach($ppd as $p){
            $optimum = $this->FtthOptimum->find($p->CodeIMB);
            if(!empty($p->type)){
                $type = $p->type;
            }else{
                $tp = $this->FtthBpu->TypeBpu(str_replace(' ', '', $p->CodeArticle));
                $type = $tp->type;
            }
            //RECHERCHE INFO OPTIMUM CAPECOM
            $oc = $this->FtthOptimumCapecom->find($p->CodeIMB);
            //SI PAS ZONE PAPM
            if($p->CodeArticle != 'CEM42'){
                //SOCIETE ATTACHE A L'IMB DE LA PPD
                if($type === 'etude'){
                    $sos = $oc->societe_etude_id;
                }elseif($type === 'travaux'){
                    $sos = $oc->societe_travaux_id;
                }
                $s = $this->FtthSociete->find($sos);
                $bpu = $this->FtthBpu->findBpu($s->id, $type, $optimum->nb_logements, $oc->fibre_id, $p->CodeArticle);
                // SI j'ai un attachement
                if(!empty($sos)){
                    if(!empty($bpu)){
                        $prix_t = $bpu->prix*$optimum->nb_logements;
                    }else{
                        $prix_t = 0;
                    }
                }else{
                    $prix_t = 0;
                }
            }else{
                //IDENTIFICATION IMB PARENT DE LA ZONE PAPM
                $dossier = $this->FtthOptimum->lastDossierByPAPM($optimum->id_pa, $optimum->id_pm);
                $imb = $dossier[0]->dossier;
                //IDENTIFICATION TOUT IMB DE LA ZONE
                $imbs = $this->FtthOptimum->lastDossierByPAPM($optimum->id_pa, $optimum->id_pm);
                //INFO TABLE ZAPAPM
                if($optimum->id_pa != ''){
                    $key = $optimum->id_pa.'_'.$optimum->id_pm;
                }else{
                    $key = $optimum->id_pm;
                }
                $z = $this->FtthZapapm->findByKey($key);
                if($p->type === 'travaux'){
                    $s = $z->ftth_societe_travaux_id;
                }elseif($p->type === 'etude'){
                    $s = $z->ftth_societe_etude_id;
                }
                if(!empty($s)){
                    $sos = $this->FtthSociete->find($s);
                    //RECHERCHE BPU
                    $bpu = $this->FtthBpu->bpuza($s, 'CEM42', $p->type);
                    if($bpu){
                        $prix_t = $bpu->prix*$optimum->nb_logements;
                    }else{
                        $prix_t = 0;
                    }
                }else{
                    $prix_t = 0;
                }
            }
            $n = $n+$prix_t;
        }
        $calcule = $this->FtthPpdCalcule->findByDate($date);
        if($calcule){
            $this->FtthPpdCalcule->update($date, [
                'prix'    => $_GET['prix'],
                'prix_s'  => $n,
                'prix_d' => round(intval($_GET['prix'])-$n, 2)
            ]);
        }else{
            $this->FtthPpdCalcule->create([
                'prix'    => $_GET['prix'],
                'prix_s'  => $n,
                'prix_d' => round(intval($_GET['prix'])-$n, 2),
                'date_debut' => $date
            ]);
        }
        return $this->index();
    }

Je pense qu'il serait possible que tu incrémentes à chaque fois que l'éxécution d'une requête est finie ainsi tu pourrais faire une barre de progression.

cid5420
Auteur

ok du coup comment je renvoie l'incrémentation vers js ?

En utilisant ajax

Ou plutôt les websokets pour éviter les multitudes de requête ajax qui retourne la même réponse. Le problème est le suivant :
Ajax méthode :
client : hei quel est ton état ?
serveur: status => 1
client (n time après) : Hei quel est ton état ?
serveur: status => 1
[...]
Et ainsi de suite.

la philosophie websocket :
Serveur : Hei j'ai changé d'état, je suis status 1
Client : j'update mon UI
serveur quand il change d'état : Hei j'ai changé d'état, je suis status 2

Ici c'est le serveur qui notifie le client qu'il a changé, et pas le client qui intéroge à interval régulier si le serveur a changé d'état.

Il faudrait que le serveur renvoie les états en mode "chunk" (rajouter le header 'Transfer-Encoding: chunked' côté serveur).
En mode chunk, la connection entre le serveur et le navigateur reste ouverte tant qu'il reste des chunk à envoyer
En js ça donne

var xhr = new XMLHttpRequest()
xhr.open("GET", "/test/chunked", true)
xhr.onprogress = function () {
  console.log("PROGRESS:", xhr.responseText)
}
xhr.send()

voir l'article ici
Côté php il suffit de flusher l'état après chaque requête