2009-08-13 10 views
1

Mon script est composé de deux parties. La première partie génère une page HTML. La deuxième partie charge un resourse du réseau et l'enregistre dans un fichier. Le chargement est une opération longue et peut durer jusqu'à 10 secondes. Les première et seconde parties sont complètement indépendantes (le chargement n'a aucun impact sur l'aspect de la page).PHP: Comment afficher la page avant la fin du script?

À la fin de la première partie, j'appelle flush(), ce qui rend la page affichée instantanément. Cependant, le film SWF incorporé n'est pas affiché pour l'instant. SWF est l'élément clé de la page et il doit être affiché aussi vite que possible. Il est incorporé dans la page avec la bibliothèque SwfObject. Et le problème est que SwfObject commence à ouvrir SWF sur l'événement "onLoad" de la page. Mais l'événement "onLoad" se trouve à la fin de la partie deuxième. C'est "onLoad" peut se produire dans 10 secondes. Ainsi, malgré l'appel de flush(), l'utilisateur doit attendre 10 secondes en vain.

Est-il possible de résoudre la tâche du côté PHP? Est-il possible d'exécuter la tâche "chargement" (la deuxième partie) dans un processus séparé? Est-il possible de dire au navigateur avant le début de la deuxième partie, que la page est reay et que vous pouvez diffuser l'événement "onLoad".

Merci d'avoir lu cette très longue histoire.

Répondre

2

Je suggère diviser votre code en deux fichiers PHP séparés:

Le premier fichier génère la page HTML contenant le fichier SWF.

Le deuxième fichier récupère la ressource et l'enregistre.

L'astuce est que dans l'événement onLoad de la première page, vous exécutez un petit extrait de JavaScript qui demande l'URL de la deuxième page.

Le code de la première page ressemblerait à quelque chose comme ceci:

... 
<body onload="makeRequest('page2.php')"> 
... 

où makeRequest est une fonction quelque chose comme celui ici: http://www.captain.at/howto-ajax-form-post-get.php

Cette marque être utile pour comprendre que AJAX Tutorial.

Bien sûr, si ces éléments sont vraiment indépendants, vous devriez envisager d'exécuter le second dans un processus ou un thread séparé. pcntl-fork peut aider ici.

+0

Que faire si JS est désactivé;)? – Wookai

+0

Ensuite, je suggère définitivement d'exécuter la deuxième partie dans un processus séparé en utilisant soit pcntl-fork ou le système. –

2

PHP ne supporte pas le threading, donc vous devrez écrire un script qui fera la seconde partie et l'exécuter en utilisant la méthode exec(). Mais ce n'est probablement pas la meilleure solution. Ce que vous pouvez probablement faire est d'oublier de déplacer la deuxième partie qui prend beaucoup de temps pour séparer action de script ou de contrôleur si vous utilisez des contrôleurs MVC. Ensuite, lancez simplement la première partie et votre page se chargera rapidement. Ensuite, vous pouvez ajouter un AJAX pour appeler ce nouveau script/action pour exécuter la deuxième partie de votre algorithme après le chargement de votre page.

+1

+1 pour MVC: il suffit de déclencher un appel d'action avec ajax après avoir chargé le swf – markus

+0

Merci, je vais essayer cette approche. – Pavel

1

Au lieu de "onload", pouvez-vous ajouter un bloc de script à la fin de la page pour initialiser votre film SWF?

+0

SWFObject ne fournit pas de méthode API pour rendre cela légal. Je préférerais éviter de pirater cette librairie. – Pavel

1

Je ne suis pas sûr, mais que se passe-t-il si vous mettez ce film SWF dans un IFRAME?

+0

Malheureusement, ce n'est pas mon cas – Pavel

0

Une approche consiste à lancer le second étage via une requête de service Web unidirectionnel provenant du premier étage. En supposant que vous utilisez PHP 5, jetez un oeil à la prise en charge SOAP.

Si le client ne charge pas après avoir appelé flush(), deux possibilités s'offrent à vous: premièrement, le serveur Web peut mettre en mémoire tampon la sortie et ne pas accéder au client; Deuxièmement, vous n'avez pas produit de page complète au moment où vous appelez flush(). Ce dernier problème devrait être facile à résoudre.

+0

La page est affichée complètement après flush(), mais l'événement "onload" n'est pas activé. Merci pour l'idée de SOAP. – Pavel

+0

Les navigateurs commenceront à afficher le contenu dès qu'ils le recevront, mais n'invoqueront pas l'événement onLoad jusqu'à la réception de la balise HTML de fermeture. Utilisez un outil de surveillance tel que Firebug ou Fiddler pour vérifier que vous envoyez réellement la page complète. – kdgregory

Questions connexes