2012-09-21 11 views
6

Potrzebuję zapewnić interakcję między js na stronie html i php-script.
- Użyj AJAX.
Ok. Ale problem polega na tym, że wykonywanie skryptu php trwa bardzo długo i muszę znać stan tego przetwarzania skryptu (na przykład 60% kompletny)
Co powinienem zrobić? Utwórz 2 php-skrypty (serwer klienta &) i wykonaj ajax-request na client.php, który wykona żądania do server.php przez gniazda lub coś podobnego? Czy istnieją bardziej eleganckie rozwiązania?JavaScript uzyskiwanie postępu skryptu PHP

+0

Cóż, używanie pliku może pomóc, ale nadal nie jest moim marzeniem. Co, jeśli muszę bardzo często pobierać informacje ze skryptu php. Czy nie byłoby to zbyt drogie dla systemu plików? – Dmitriy

+0

Czytanie pliku jest absurdalnie łatwe dla komputerów. – thatidiotguy

Odpowiedz

2

Co jeśli miał skrypt robi przetwarzanie napisać swój status do pliku raz na jakiś czas. Zrób drugi skrypt, który odczyta plik i zwróci stan oryginalnego.

2
  1. Skrypt php wywołania Ajax i informacje o powrocie, które uruchamia skrypt.
  2. Główny skrypt tworzy plik lock.file.
  3. Skrypt wywołany z crona sprawdza, czy plik lock.file istnieje i uruchamia poprawny skrypt.
  4. Poprawny skrypt zapisuje bieżące postępy w pliku progress.txt.
  5. Ajax czyta progress.txt, a kiedy postęp jest w 100%, zwraca informację, że przetwarzanie skryptu zostało zakończone.

edycja: Dzięki Justin dla poiting problemu limitu czasu;)

+0

Nawet jeśli 'fork()' w głównym skrypcie wykona przetwarzanie w tle, twój serwer HTTP nadal może przerwać żądanie, jeśli jest ono długotrwałe. Istnieją różne sposoby, ale lepszym rozwiązaniem jest przeniesienie czasochłonnego procesu całkowicie poza zakres odpowiedzialności serwera WWW. –

+0

Oczywiście, ale główny skrypt zamiast operacji przetwarzania może tylko utworzyć plik blokady, a następnie inny skrypt uruchamiany z crona, gdy plik blokady istnieje, może uruchomić główny proces. Skrypty wywoływane z cli zwykle nie mają żadnego czasu oczekiwania :) –

+0

Powinieneś prawdopodobnie zaktualizować odpowiedź, aby to uwzględnić. Sposób, w jaki obecnie jest napisany (* "Główny skrypt zapisuje postęp do pliku progress.txt" *) nie wyjaśnia, że ​​"główny skrypt" jest wykonywany przez crona i szuka sygnału do rozpoczęcia przetwarzania. –

1

Jeśli chcesz być naprawdę fantazyjne, pisać wyjście ze skryptu php do stdout i uchwycić go rurą. Wymagałoby to uruchomienia skryptu php przy użyciu exec() lub proc_open() (http://php.net/manual/en/function.proc-open.php) i wyprowadzenia danych wyjściowych do pliku (lub jeśli chcesz być extra-extra fantazyjne, użyj node.js słuchać do tych danych)

Istnieje sporo sposobów, aby to osiągnąć:

  • node.js
  • kwerenda Ajax co x sekund
  • Przeładowanie strony META/JavaScript
  • Element iframe, który jest rutynowo przeładowywany wraz ze statusem.

Powodzenia!

2

Nie powinieneś nigdy wykonywać długiego procesu całkowicie w ramach sesji HTTP.

Prosta i wspólne podejście do tego problemu jest kolejkowania wiadomości. Zasadniczo masz kolejkę UI do żądania do tabeli bazy danych, a następnie demona (ów) zewnętrznego przetwarzania kolejki.

Aby przekazać opinię, mieć demon okresowo aktualizować tabelę ze statusem dla rzędu obecnie pracuje na to. Następnie Twój kod javascript może wysyłać żądania AJAX do skryptu, który pobiera status tego elementu pracy z bazy danych i wyświetla go użytkownikowi.

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

0

Można użyć buforowania wyjścia PHP (patrz ob_flush) opróżnić zawartość w określonych punktach w skrypcie JavaScript i dostosować tak, że używa się spłukuje zawartość.Wierzę, że readyState w twoim wywołaniu AJAX nie zostanie ustawione na 4 w opróżnianiu, więc tam będziesz musiał sobie z tym poradzić (patrz this article). Myślę, że jest to o wiele ładniejszy sposób niż zapisywanie do pliku i sprawdzanie jego zawartości.

0

na swojej 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; 

na swój progress.php:

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

teraz od swojej stronie klienta, po prostu złożyć zamówienie na swojej progress.php, otrzyma numer i dać go do postępu bar ...

nie sprawdziłem tego sam, ale mam nadzieję, że to działa! :)