2012-09-21 14 views
6

Ich muss Interaktion zwischen js auf HTML-Seite und PHP-Skript bereitstellen.
- Verwenden Sie AJAX.
Ok. Aber das Problem ist, dass php-Skript für eine lange Zeit ausgeführt wird, und ich muss den Status dieser Skriptverarbeitung wissen (z. B. 60% abgeschlossen)
Was soll ich tun? Erstellen Sie 2 PHP-Skripte (Client & Server) und machen Sie eine AJAX-Anfrage an die client.php, die Anfragen an server.php über Sockets oder SMTP sendet? Gibt es elegantere Lösungen?Javascript bekommen Fortschritt von PHP-Skript

+0

Nun, mit Datei kann helfen, aber es immer noch nicht mein Traum. Was ist, wenn ich sehr oft Informationen von PHP-Skript bekommen muss. Wäre das nicht zu teuer für das Dateisystem? – Dmitriy

+0

Das Lesen einer Datei ist für Computer lächerlich einfach. – thatidiotguy

Antwort

2

Was wäre, wenn Sie das Skript, das die Verarbeitung durchführt, ab und zu in eine Datei schreiben? Erstellen Sie ein zweites Skript, das die Datei liest und den Status des Originals zurückgibt.

2
  1. Ajax rufen PHP-Skript und Informationen zurück, dass Skript ausgeführt wird.
  2. Hauptskript erstellen lock.file.
  3. Skript von cron aufgerufen prüft, ob lock.file existiert und das richtige Skript ausführen.
  4. Das korrekte Skript speichert den aktuellen Fortschritt in progress.txt.
  5. Ajax liest die Datei progress.txt und wenn der Fortschritt 100% ist, geben Sie die Information zurück, dass die Skriptverarbeitung abgeschlossen ist.

bearbeitet: Dank Justin für poiting das Timeout Problem;)

+0

Auch wenn Sie 'gabel()' innerhalb des Hauptskriptes verwenden, um die Verarbeitung im Hintergrund durchzuführen, kann Ihr HTTP-Server die Anfrage immer noch abbrechen, wenn sie lange läuft. Es gibt Möglichkeiten, aber die bessere Lösung besteht darin, den zeitaufwändigen Prozess komplett außerhalb des Verantwortungsbereichs des Webservers zu verschieben. –

+0

Sicher Sache, aber Hauptskript statt Verarbeitungsvorgang kann nur eine Sperrdatei erstellen und dann ein anderes Skript, das von Cron ausgeführt wird, wenn Sperrdatei vorhanden ist, Hauptprozess ausführen kann. Skripte, die von cli usualy aufgerufen werden, haben kein Timeout :) –

+0

Sie sollten die Antwort wahrscheinlich aktualisieren, um sie einzuschließen. Die Art und Weise, wie es aktuell formuliert ist (* "Hauptskript-Schreibfortschritt in progress.txt-Datei" *) macht nicht deutlich, dass das "Hauptskript" von cron ausgeführt wird und nach einem Signal sucht, um mit der Verarbeitung zu beginnen. –

1

Wenn Sie wirklich Lust sein wollen, schreiben Sie Ausgabe aus dem PHP-Skript auf stdout und erfassen sie über ein Rohr. Dies würde erfordern, das php-Skript mit exec() oder proc_open() (http://php.net/manual/en/function.proc-open.php) auszuführen und die Ausgabe in eine Datei zu pipen (oder wenn Sie es wollen) Extra-Extra Phantasie, verwenden node.js für diese Daten)

Es gibt durchaus ein paar Möglichkeiten, dies zu tun zu hören:

  • Node.JS
  • Eine Abfrage Ajax alle x Sekunden
  • Eine META/Javascript-Seite wird neu geladen.
  • Ein Iframe, das routinemäßig den Status neu lädt.

Viel Glück!

2

Sie sollten niemals einen lang andauernden Prozess ausführen, der vollständig innerhalb einer HTTP-Sitzung ausgeführt wird.

Ein einfacher und allgemeiner Ansatz für dieses Problem ist Message Queuing. Grundsätzlich müssen Sie Ihre UI die Anfrage in eine Datenbanktabelle einreihen lassen und dann die Warteschlange von externen Daemon (en) verarbeiten lassen.

Um Feedback zu geben, muss der Daemon die Tabelle regelmäßig mit dem Status der Zeile aktualisieren, an der er gerade arbeitet. Dann kann Ihr JavaScript-Code AJAX-Anforderungen an ein Skript stellen, das den Status für dieses Arbeitselement aus der Datenbank abruft und es dem Benutzer anzeigt.

See: Dealing with long server-side operations using ajax?

0

Sie PHP Ausgabepufferung verwenden könnten (siehe ob_flush), den Inhalt an bestimmten Punkten in Ihrem Skript zu spülen und sie JavaScript anzupassen, damit es den gespülten Inhalt verwendet.Ich glaube, readyState in deinem AJAX-Call wird bei Flush-Aktionen nicht auf 4 gesetzt, also musst du damit selbst umgehen (siehe this article). Ich denke, es ist eine viel schönere Art, als in eine Datei zu schreiben und den Inhalt davon zu überprüfen.

0

auf process.php:

// 1st task 
$_SESSION['progress'] = 0; 

// your code for the first task here ... 

// 2nd task 
$_SESSION['progress'] = 10; 

// you code for 2nd task ... 

// 3rd task 
$_SESSION['progress'] = 17; 

// continue ... 

// everything finished? 
$_SESSION['progress'] = 100; 

auf progress.php:

// simply output 
echo $_SESSION['progress']; 

jetzt von Ihrem Client-Seite, stellen Sie einfach eine Anfrage an Ihre progress.php, erhalten die Nummer und geben Sie es an Ihre Fortschritte bar ...

habe ich das nicht selbst überprüft, hoffe aber, dass es funktioniert! :)