2011-12-17 11 views
10

scenariusz:najbardziej prosty sposób, aby rozpocząć nowy proces/wątek w PHP

  1. dzielonego hostingu, więc nie ma możliwości, aby zainstalować nowe rozszerzenia + nie CRON
  2. Złożone prośba musi wykonać pewne ciężkie procesy.
  3. Chcę, aby odpowiedź dla klienta była tak szybka, jak to możliwe, a podnoszenie ciężarów jest kontynuowane, ale nie zatrzymujemy klienta.
  4. może być na nowym wątku (jeśli to możliwe) również nie ma problemu z rozpoczęciem nowego procesu.

Jaki jest najlepszy sposób na zrobienie tego?

+0

PHP nie (obecnie) jest wielowątkowe. * Wiele * na moje regularne niezadowolenie. – DaveRandom

+0

Cóż, niektóre rzeczy można emulować. –

Odpowiedz

11

W * nix:

exec('/path/to/executable > /dev/null 2>&1 &'); 

W systemie Windows:

$WshShell = new COM('WScript.Shell'); 
$oExec = $WshShell->Run('C:\path\to\executable.exe', 0, false); 

Oba z nich będzie tarło nowy proces, który uruchomi synchronicznie, całkowicie odłączony od rodzica. Tak długo, jak pozwala na to twój host.

+0

Czy mogę zmienić/dev/null na wybrany przeze mnie plik dziennika? –

+0

Myślę, że tak długo, jak przekierowujesz STDOUT * i * STDERR do miejsca, które nie jest procesem nadrzędnym, i sufiksem z '&', powinno działać.TBH, zawsze miałem po prostu '/ dev/null', więc naprawdę musisz po prostu go zasysać i zobaczyć ... – DaveRandom

+0

Rozpocznij dowolny zewnętrzny proces na współdzielonym hostingu? Powodzenia z tym. –

1

Brak wątków w PHP. Możesz oszukać, wysyłając stronę HTML, która wyzwala wywołanie Ajax, aby rozpocząć ciężki proces w nowym żądaniu. Ale jeśli jest to dzielony hosting, domyślam się, że szybko przekroczysz limit pamięci, czasu lub użycia procesora nałożony przez dostawcę usług hostingowych.

+0

[Najwyraźniej teraz istnieją wątki w PHP] (http://docs.php.net/manual/en/class.thread.php), ale być może trzeba je [zainstalować] (http: //docs.php. net/manual/en/pthreads.installation.php). Jednak tego wieczoru tego właśnie się nauczyłem, więc jeszcze tego nie próbowałem. – Volomike

0
$WshShell = new COM('WScript.Shell'); 
$oExec = $WshShell->Run('C:\xampp\php\php.exe C:\xampp\htdocs\test.php -a asdf', 0, true); 

Nie można przekazać argv do test.php.

var_dump($argv); 
+1

Zakładam, że to jest windows ...? –

2

Możesz użyć klucza Google: php kontynuuje przetwarzanie po zamknięciu połączenia.

Poniższe linki, które odnoszą się do problemu, to:

Można użyć należą polecenia, aby kontynuować wykonywanie bez przerywania użytkownik

ignore_user_abort(true); 
set_time_limit(0); 

Używasz fastcgi_finish_request do ostrzeżenia klienta, aby zatrzymać wyjście odpowiedzi. A twoje skrypty nadal będą wykonywane.

Przykład:

// redirecting... 
ignore_user_abort(true); 
set_time_limit(0); 
header("Location: ".$redirectUrl, true); 
header("Connection: close", true); 
header("Content-Length: 0", true); 
ob_end_flush(); 
flush(); 
fastcgi_finish_request(); // important when using php-fpm! 

sleep (5); // User won't feel this sleep because he'll already be away 

// do some work after user has been redirected 
+0

Witamy w SO. Powinieneś przejrzeć formatowanie swojej odpowiedzi. Jak na razie wygląda na to, że umieszczasz wszystko w bloku kodu, podczas gdy część twojej odpowiedzi to nie kod. – Laf

+0

Dziękuję Laf. Przeformatowałem swoją odpowiedź. –

Powiązane problemy