Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Skrytpt w tle
Forum PHP.pl > Forum > PHP
markonix
Pewien INSERT, który dla użytkownika końcowego jest raczej niczym wielkim, powoduje bardzo dużo zależnych akcji (wysyłka dużej ilości maili i inne).
Jest jakiś trik żeby w momencie gdy INSERT się wykona odpalić skrypt w osobnym wątku tak aby on nie czekał na efekt tych działań?
Najlepiej bez CRON'a.
daniel1302
Jeśli masz dostęp do poleceń shella (w php funkcja exec) to nie ma problemu bo wykonujesz:
  1. exec('php /adres/do/pliku.php');


Musisz posiadać zainstalowane rozszeżenie PHP-CLI, w niektórych distro linuxa da się doinstalować z repo np w debian apt-get install php-cli. A jak nie to niema problemu skompilować. No i deamon php musi posiadac uprawnienia do wykonania polecenia php w konsoli

Skrypt musisz odpalić poprzez ajax, bo jak nie to i tak będzie czejał aż exec zwróci jakiś wynik. Albo możesz testować normalny plik z php przez ajax, jednak nieasynchroniczny(wykona się w tle). Ale ktoś będzie mógł przerwać wykonywanie w połowie i zależnie od kofigu serwera skrypt może się nie wykonać.
markonix
Mało wygodne rozwiązanie i niestety to nie mój serwer więc odpada.

Wywołanie AJAXem też odpada - to są kluczowe akcje ale nie dla użytkownika tylko logiki systemu dlatego jeśli by zablokował skrypty będzie nieciekawie.
Tak samo myślałem o iframe - otwiera mu się strona z potwierdzeniem "Dodania", a w iframe wykonuje się akcja.
Z tego co wiem nawet jak się zamknie stronę to PHP nadal będzie działał (pętla).
Ale jakoś takie rozwiązanie brzydko mi pachnie no i są skrajności że iframe też ma zablokowane.
daniel1302
No to jak w iframie nie przerwie skryptu po wyłączeniu to serwer jest skonfigurowany tak, ze dla ajaxa tez nie przerwie po wylączeniu pliku, czyli problemu nie masz.
markonix
To i to nie ma różnicy - chodzi o pewność wywołania, przecież taki ajax to raz na 10 razy się nie wywoła, a taki iframe raz na 1000.
I to już nie tylko ze względu na ustawienia przeglądarki ale też po prostu nie zdąży np. załadować strony mimo że insert się wykonał.

Ogólnie myślałem bardziej coś na zasadzie fopen - po insert po prostu łączy się z innym kontrolerem tylko pytanie jak zrobić aby nie czekał na odpowiedź?
daniel1302
Niestety ale nie jest to dynamiczny język. Ale sprawdź to:
mysql_unbuffered_query
markonix
http://stackoverflow.com/questions/124462/...onous-php-calls
tu coś znalazłem, potestuje i dam znać.

To nie działa tak jakbym chciał sad.gif

http://stackoverflow.com/questions/2190854...ng-for-response

Zostaje CRON odpalany co minutę :/
sabat24
A wysłanie GETa zamiast POSTa nie rozwiązuje sprawy? Swego czasu tak robiłem na hostingu, gdyż tam nie można odpalać demonów (rozumiem, że nie masz dostępu do serwera, aby to zrobić), kiedy chciałem wygenerować PDFa i wysłać e-maila dołączając go jako załącznik. Działało sprawnie.
abort
Nie testowałem, ale może można spróbować dodać "&" do parametru "exec", np
  1. $cmd = "/path/to/file";
  2. exec ($cmd . "&");

W normalnym uniksie powoduje to wywołanie programu w tle. A jak wiemy, exec czeka na wykonanie się polecenia. No to poczeka tylko chwileczkę, dopóki shell nie zamelduje mu, że polecenie się wykonało. A że w tle? Chyba o to Ci chodzi.
Spróbuj,potestuj, daj znać.

aha, notka z manuala do exec:
Kod
Note: If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

Reasumując, powinno być chyba bardziej tak:
Kod
$cmd = "/path/to/file";
$background = ">/dev/null 2>/dev/null &";
exec ($cmd . $background);

Oczywiście, redirectowanie standard output/error możesz dać do pliku, jeśli chcesz/potrzebujesz. Ja dałem do /dev/null, bo zakładam, że nie interesuje Cię to co program ewentualnie wypluwa (albo wręcz jest tak, że nie wypluwa nic).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.