PHP - bouffées de chaleur lors de la Boucle de Données avec l'Ajax
À l'aide de PHP, je voudrais faire une boucle while qui lit un fichier de grande taille et envoie le numéro de ligne courant lorsqu'il est demandé. À l'aide d'Ajax, je voudrais avoir l'actuelle ligne de comte et de l'imprimer sur une page. À l'aide des boutons html, je voudrais être en mesure de cliquer et d'activer ou de mettre fin à un javascript thread qui s'exécute une seule FOIS et appelle la ajax méthode.
J'ai donné un coup de feu, mais pour une raison quelconque, rien ne s'imprime à moins que j'en commentaire le echo str_repeat(' ',1024*64);
fonction et quand il est commenté, il montre la totalité de la boucle résultat:
1 ligne(s) de traitement.2 ligne(s) de traitement.3 ligne(s) de traitement.4 ligne(s) de traitement.5 ligne(s) de traitement.6 ligne(s) de traitement.7 ligne(s) de traitement.8 ligne(s) de traitement.9 ligne(s) de traitement.10 de ligne(s) de traitement.
En une seule ligne au lieu de les montrer dans des lignes distinctes comme:
1 row(s) processed.
2 row(s) processed.
3 row(s) processed.
4 row(s) processed.
5 row(s) processed.
6 row(s) processed.
7 row(s) processed.
8 row(s) processed.
9 row(s) processed.
10 row(s) processed.
Aussi je ne suis pas sûr de la façon de mettre fin à l'JavaScript fil. Donc 2 problèmes au total:
1. It's returning the entire While loop object at once instead of each time it loops.
2. I'm not sure how to terminate the JQuery thread.
Des idées? Ci-dessous mon code jusqu'à présent.
msgserv.php
<?php
//Initiate Line Count
$lineCount = 0;
//Set current filename
$file = "test.txt";
//Open the file for reading
$handle = fopen($file, "r");
//Change Execution Time to 8 Hours
ini_set('max_execution_time', 28800);
//Loop through the file until you reach the last line
while (!feof($handle)) {
//Read a line
$line = fgets($handle);
//Increment the counter
$lineCount++;
//Javascript for updating the progress bar and information
echo $lineCount . " row(s) processed.";
//This is for the buffer achieve the minimum size in order to flush data
//echo str_repeat(' ',1024*64);
//Send output to browser immediately
flush();
//Sleep one second so we can see the delay
//usleep(100);
}
//Release the file for access
fclose($handle);
?>
asd.html
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css" media="screen">
.msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
.new{ background-color:#3B9957;}
.error{ background-color:#992E36;}
</style>
</head>
<body>
<center>
<fieldset>
<legend>Count lines in a file</legend>
<input type="button" value="Start Counting" id="startCounting" />
<input type="button" value="Stop Counting!" onclick="clearInterval(not-Sure-How-To-Reference-Jquery-Thread);" />
</fieldset>
</center>
<div id="messages">
<div class="msg old"></div>
</div>
<script type="text/javascript" charset="utf-8">
function addmsg(type, msg){
/* Simple helper to add a div.
type is the name of a CSS class (old/new/error).
msg is the contents of the div */
$("#messages").append(
"<div class='msg "+ type +"'>"+ msg +"</div>"
);
}
function waitForMsg(){
/* This requests the url "msgsrv.php"
When it complete (or errors)*/
$.ajax({
type: "GET",
url: "msgsrv.php",
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:2880000, /* Timeout in ms set to 8 hours */
success: function(data){ /* called when request to barge.php completes */
addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
setTimeout(
'waitForMsg()', /* Request next message */
1000 /* ..after 1 seconds */
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
addmsg("error", textStatus + " (" + errorThrown + ")");
setTimeout(
'waitForMsg()', /* Try again after.. */
"15000"); /* milliseconds (15seconds) */
},
});
};
$('#startCounting').click(function() {
waitForMsg();
});
</script>
</body>
</html>
test.txt
1
2
3
4
5
6
7
8
9
10
Vous devez vous connecter pour publier un commentaire.
À l'aide de:
ignore_user_abort()
ob_flush()
doivent faire tout ce dont vous avez besoin dans un php fil
MODIFIER
Prendre un coup d'oeil à nickb réponse, si vous êtes à la recherche d'un moyen de le faire simplement, il serait algorithme suivant:
process.php
via ajax (qui va faire tout le travail ET l'état de l'impression des rapports), vous avez à regarder si jQuery ajax prend en charge le chargement continuDans
process.php
:EDIT 2 demandée exemple (peu différents et laid, mais simple).
test_process.php
:Et la page html principale:
Après frapper démarrer lignes comme:
Paru dans le div
#foo
. Quand j'ai frappéStop
, ils ont cessé de paraître, mais la fin du script en tâche de fond et écrit tous les 100 numéros dans le fichier.Si vous frappez
Start
nouveau script commence à s'exécuter à partir de la mendicité (fichier de réécriture) ce serait parallèle demande de faire.Pour plus d'info sur http streaming voir ce lien
Vous êtes confus quant à la façon dont PHP et AJAX interagir.
Lorsque vous demandez la page PHP via AJAX, vous forcez le script PHP, pour commencer l'exécution. Bien que vous pourriez être en utilisant
flush()
pour effacer tous les internes de PHP tampons, de l'appel AJAX a remporté pas arrêter (c'est à dire, les gestionnaires de réponse ne sera pas appelé) jusqu'à ce que la connexion est fermée, ce qui se produit lorsque la totalité du fichier a été lu.Pour accomplir ce que vous cherchez, je crois que vous auriez besoin d'un processus parallèle de flux comme ceci:
Que vous pourriez accomplir cette communication inter-processus par le biais de
$_SESSION
variables, ou en stockant les données dans une base de données. De toute façon, vous avez besoin d'un parallèle mise en place de votre séquentiel, sinon, vous continuerez à obtenir la totalité de l'état à la fois.Solution la plus simple devrait être à l'aide de l'indigène (vanila js) XHR objet.
Il est très sophistiqué solutions là-bas, sur le temps d'interrogation
Le PHP:
Le JS:
L'astuce est de créer un fichier (mise à jour via Ajax) et l'utilisation d'un
setInterval
pour obtenir sa valeur, puis mettre à jour la barre de progression.