Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 22-02-2008 12:02:19

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Solution pour afficher un message d'attente entre toutes les pages

Bonjour à tous,

Je voudrais afficher des messages d'attente (chargment en cours...) entre toutes les vues de mon appli. Ce message pourra donc rester affiché plusieurs secondes si le controlleur a beaucoup de traitements à faire, et desfois très peu si le traitement est très rapide.

Le but c'est que l'utilisateur ne croie pas que l'appli a planté, mais qu'il soit informé qu'elle travaille.

Je cherche donc un endroit dans mon code ZF (bootstrap, init() d'un controleur, etc.) pour placer un code qui par exemple affichera en JS un div flottant qui contiendra le message d'attente, puis le retirera à la fin de l'exécution du script.

J'ai commencé une serie de tests non concluante (avec des flush(), des ob_start(), etc.), je cherche encore donc si vous avez déjà fait ca je suis preneur.

Merci d'avance !

Hors ligne

 

#2 22-02-2008 12:25:30

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: Solution pour afficher un message d'attente entre toutes les pages

A ma connaissance, là je vois mal comment c'est possible, car tu ne peux pas envoyer de sortie pendant que le script est toujours en cours d'execution.

Hors ligne

 

#3 22-02-2008 12:58:45

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Logiquement les fonctions ob_.... et flush sont là pour ca, je cherche encore, pour le moment j'ai rien de génial

Hors ligne

 

#4 22-02-2008 13:07:44

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: Solution pour afficher un message d'attente entre toutes les pages

Pour moi, les fonctions ob_... permettent de bloquer/capturer la sortie dans un buffer et non de renvoyer un partie en attendant la fin du script: http://fr.php.net/ob_start
J'te dis ça pour pas que tu cherches mille ans à faire un truc impossible... j'dis ça, j'dis rien... smile

Hors ligne

 

#5 22-02-2008 13:10:54

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Je confond avec flush qui permet de forcer l'envoie du contenu du buffer au navigateur : http://www.manuelphp.com/php/function.flush.php

Cependant je me demande si mon souci (flush() ne fonctionne pas chez moi) ne viens pas du fait que le serveur web est sous windows...

Hors ligne

 

#6 22-02-2008 13:46:21

TiTerm
Membre
Date d'inscription: 01-07-2007
Messages: 175

Re: Solution pour afficher un message d'attente entre toutes les pages

Flush fonctionne même sous windows... Maintenant, si tu as un ob_start, et tu en as probablement un avec le viewRenderer, le flush ne fera rien puisqu'il y a un buffer actif. De puis, il y a aussi apache qui peut buffuriser et ca ,tu ne maitrisera pas via php.

La seule solution que je voie a ton pb, c'est de faire trapper les clicks coté browser et afficher ton message d'attente puis de faire l'appel a l'url contrôleur/action en ajax. Ensuite, une fois la réponse obtenu, tu l'affiches et tu caches ton messages d'attente

Hors ligne

 

#7 22-02-2008 13:55:23

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Si je fais ca :

public function preDispatch(Zend_Controller_Request_Abstract $request){
    echo "Debut loading";flush();
}

j'ai bien la sortie avant le rendu final de la vue, par contre je comptais utiliser postDispatch pour cacher le fameux div mais postDispatch est executé bien avant le rendu final, en fait il est executé juste après preDispatch.

Il me faudrait trouver une méthode du controleur principal de Zend qui serait executée le plus tard possible pour ne pas que le message soit effacé trop tot.

Pour ta méthode de listeners sur les liens, c'est trop lourd à mettre en place sur mon projet je ne peux pas.

TiTerm a écrit:

Flush fonctionne même sous windows...

La doc PHP dit que sous Windows ca merde souvent...

Dernière modification par vallica (22-02-2008 13:56:48)

Hors ligne

 

#8 22-02-2008 14:12:11

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Erf, c'est moi qui merde en fait dans mon bootstrap, je me suis servi du preDispatch et du postDispatch de mon plugin d'authentification, c'est surement pour cela que le postDispatch s'exécute très tôt.

Je cherche maintenant comment faire pour "accrocher" un plugin en tout début d'execution du bootstrap, et un autre en toute fin (après le render) qui servira à faire disparaitre le message.

Hors ligne

 

#9 22-02-2008 14:16:01

ndesaleux
Membre
Date d'inscription: 16-04-2007
Messages: 196
Site web

Re: Solution pour afficher un message d'attente entre toutes les pages

je verrai a la rigueur une fonction JS qui au (onload / debut de ton body) lance affiche ton div, et le masque en fin de page, c'est de l'interactif, je ne vois pas en quoi PHP peut t'aider pour cela.

Hors ligne

 

#10 22-02-2008 14:23:47

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Ta solution ne peut pas fonctionner dans mon cas car le body n'est pas envoyé au navigateur avant 5 bonnes secondes (le temps que le script php prépare les données)

Hors ligne

 

#11 22-02-2008 14:28:13

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: Solution pour afficher un message d'attente entre toutes les pages

Ca pourrait t'aider à comprendre un peu mieux le déroulement du MVC avec le zf...

Hors ligne

 

#12 22-02-2008 14:28:15

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

J'ai essayé avec ce plugin mais ce n'est pas bon non plus sad

Code:

class GcpWaitingPlugin extends Zend_Controller_Plugin_Abstract {
    public function __construct() {}

    public function preDispatch(Zend_Controller_Request_Abstract $request){
        $this->getResponse()->appendBody("<div id='waiting' style='position:absolute; top:200px; z-index:10;'>Chargement des données en cours, veuillez patienter...</div>");
        flush();
    }

    public function dispatchLoopShutdown() {
        $this->getResponse()->appendBody("fini");
    }
}

C'est à dire que j'ai l'ancienne page+le sablier pendant 5 secondes et ensuite ma nouvelle page d'un coup avec mon div au milieu et le "fini" en dessous qui apparaissent simultanément.

Hors ligne

 

#13 22-02-2008 15:34:19

Geoffrey
Membre
Lieu: 63
Date d'inscription: 12-04-2007
Messages: 140
Site web

Re: Solution pour afficher un message d'attente entre toutes les pages

Bonjour,

Une solution barbare que j'utilise souvent quand je sais qu'une page risque de prendre du temps à s'afficher.

J'appelle une page ou il n'y a aucun traitement, juste une page en fait qui dis de patienter. Dans cette page je fais un ob_start() et un ob_flush() et tout de suite apres mon ob_flush, je fais un header('Location:ma-page-longue.php') avec pareil, un ob_start et un ob_flush() a la fin. Du coup, pendant que mon fichier ma-page-longue.php réfléchi, la page pour patienter reste à l'écran.

C'est un peu bourrin mais ca a toujours marché smile

Hors ligne

 

#14 22-02-2008 16:05:43

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Ok merci du tuyaux, pour l'instant j'ai réussi en lancant une thickbox lorsque je quitte la page, ce qui fait qu'elle se ferme lorsque la "longue" page a terminé de se charger. Le résultat est bon, seulement j'aurais preferé une solution coté serveur.

Hors ligne

 

#15 22-02-2008 18:22:56

Julien
Membre
Date d'inscription: 16-03-2007
Messages: 501

Re: Solution pour afficher un message d'attente entre toutes les pages

C'est difficile, en fait tout est contenu dans l'objet de réponse.
L'objet de réponse est un conteneur d'en-tête et de corps, il est vidé à la fin du processus MVC par le FrontController (par défaut), de manière à s'assurer que justement, les en-têtes comme le corps de la réponse (complète) soient rendus en une seule passe, ce qui optimise les échanges entre les buffers PHP <-> Apache <-> TCP.

Si tu echo à un moment, tu risque de troubler la réponse qui ne pourra plus se rendre car les en-têtes auront déja été envoyés. Et si c'est après le dispatching, alors les buffers vont capturer ce echo.

La demi-solution consisterait à passer par 2 dispatching, un premier light avec un message please wait envoyé, et le lourd après, mais en espérant que le lourd ne génère pas d'en-têtes (ce qui n'est pas sûr du tout), sinon ca va foirer.

Il n'existe pas vraiment de solution viable dans 100% des cas, sans avoir un client actif (AJAX).
C'est le protocole HTTP qui repose sur ce principe : une fois qu'on envoie un corps de réponse, alors les en-têtes de celle-ci sont envoyés et ne peuvent plus être régénérés.

Tu peux passer par des codes 3xx (comme un Location qui génère un 302 par défaut), mais ca n'est sémantiquement pas correct, ça voudrait dire que chaque page a changé d'adresse, les moteurs de recherche risquent de ne pas apprécier.

Hors ligne

 

#16 22-02-2008 18:28:24

vallica
Membre
Date d'inscription: 25-10-2007
Messages: 34

Re: Solution pour afficher un message d'attente entre toutes les pages

Merci Julien pour ces explications, pour ce qui est de mon cas, je bosse sur une appli web sécurisée et utilisée en intranet donc il n'y aurait pas d'inconvenient à utiliser des Location pour afficher le message d'attente.

Pour le moment je reste sur ma thickbox lancée lorsque je quitte la page qui me permet de faire un bel effet du point de vue graphique.

Coté compatibilité, étant donné que mes utilisateurs utilisent un de mes navigateurs maison basé sur Gecko, je suis sur que JS est activé et qu'ils ne pourront ni arreter le chargement ni naviguer par précedent/suivant ce qui me convient pour le moment.

Merci en tous cas pour votre aide, et bon dev wink

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages