Muszę wykonać kopię katalogu po akcji użytkownika, ale katalogi są dość duże, więc chciałbym móc wykonać taką akcję bez uświadomienia użytkownikowi czasu potrzebnego na wykonanie kopii.
Użyłem tego, ale zaktualizowałem go nieco, więc nie musiałem zapisywać PID do pliku. Używam więc tego formatu: <code> exec (sprintf ("$ s> $ s 2> & 1 & echo $ 1", $ cmd, $ outputfile), $ pidArr); </code> Wynikowy proces PID jest w $ pidArr [0]
Napisz proces jako skrypt po stronie serwera w dowolnym języku (php / bash / perl / etc), a następnie wywołaj go z funkcji kontroli procesu w skrypcie php.
Funkcja prawdopodobnie wykrywa, czy jako strumień wyjściowy zastosowano standardowe io, a jeśli tak, to ustawi wartość zwracaną .. jeśli nie, to kończy się
To jedyny sposób, w jaki mogłem zmusić go do pracy na centach. Dziękuję Ci!
Deac Karns,
Dzięki ! Istnieje niezgodność PHP i BASH. Jeśli uruchomisz nowszy system, uruchomienie w tle nie powiedzie się za pomocą system () lub exec (). Deskryptory plików wydają się blokować nawet w przypadku przekierowania. Twoja metoda zadziałała. Inną alternatywą jest użycie starego binarnego basha dla PHP, ale to wariactwo
Jan
22
Możesz spróbować dołączyć to do swojego polecenia
>/dev/null2>/dev/null&
na przykład.
shell_exec('service named reload >/dev/null 2>/dev/null &');
To działa dla mnie i użyję makefile, aby zrobić coś na stronie serwera, dziękuję! (np. make, make restart)
Chu-Siang Lai
Jest to o wiele prostsze niż zaakceptowana odpowiedź! (Tak długo, jak nie potrzebujesz nic bardziej złożonego, na przykład sprawdzania, czy proces nadal działa.)
Sean the Bean
18
Chciałbym tylko dodać bardzo prosty przykład testowania tej funkcji w systemie Windows:
Utwórz następujące dwa pliki i zapisz je w katalogu internetowym:
foreground.php:
<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
echo "<pre>loading page</pre>";function run_background_process(){
file_put_contents("testprocesses.php","foreground start time = ". time()."\n");
echo "<pre> foreground start time = ". time()."</pre>";// output from the command must be redirected to a file or another output stream // http://ca.php.net/manual/en/function.exec.phpexec("php background.php > testoutput.php 2>&1 & echo $!", $output);
echo "<pre> foreground end time = ". time()."</pre>";
file_put_contents("testprocesses.php","foreground end time = ". time()."\n", FILE_APPEND);return $output;}
echo "<pre>calling run_background_process</pre>";
$output = run_background_process();
echo "<pre>output = "; print_r($output); echo "</pre>";
echo "<pre>end of page</pre>";?>
background.php:
<?
file_put_contents("testprocesses.php","background start time = ". time()."\n", FILE_APPEND);
sleep(10);
file_put_contents("testprocesses.php","background end time = ". time()."\n", FILE_APPEND);?>
Zezwól IUSR na zapis w katalogu, w którym utworzono powyższe pliki
Zezwól IUSR na CZYTANIE I WYKONYWANIE C: \ Windows \ System32 \ cmd.exe
Hit foreground.php z przeglądarki internetowej
Poniższe powinny zostać wyświetlone w przeglądarce z aktualnymi znacznikami czasu i zasobem lokalnym # w tablicy wyjściowej:
loading page
calling run_background_process
foreground start time =1266003600
foreground end time =1266003600
output =Array([0]=>15010)endof page
Powinieneś zobaczyć testoutput.php w tym samym katalogu, w którym zostały zapisane powyższe pliki, i powinien być pusty
Powinieneś zobaczyć testprocesses.php w tym samym katalogu, w którym zostały zapisane powyższe pliki, i powinien zawierać następujący tekst z aktualnymi znacznikami czasu:
foreground start time =1266003600
foreground end time =1266003600
background start time =1266003600
background end time =1266003610
Jeśli potrzebujesz zrobić coś w tle bez oczekiwania strony PHP na zakończenie, możesz użyć innego (w tle) skryptu PHP, który jest „wywoływany” poleceniem wget. Ten skrypt PHP w tle będzie wykonywany z uprawnieniami, oczywiście, jak każdy inny skrypt PHP w twoim systemie.
Oto przykład systemu Windows używającego wget z pakietów gnuwin32.
Kod w tle (plik test-proc-bg.php) jako przykład ...
sleep(5);// some delay
file_put_contents('test.txt', date('Y-m-d/H:i:s.u'));// writes time in a file
Oto funkcja umożliwiająca uruchomienie procesu w tle w PHP. W końcu stworzyłem taki, który faktycznie działa również w systemie Windows, po wielu odczytach i testach różnych podejść i parametrów.
functionLaunchBackgroundProcess($command){// Run command Asynchroniously (in a separate thread)if(PHP_OS=='WINNT'|| PHP_OS=='WIN32'|| PHP_OS=='Windows'){// Windows
$command ='start "" '. $command;}else{// Linux/UNIX
$command = $command .' /dev/null &';}
$handle = popen($command,'r');if($handle!==false){
pclose($handle);returntrue;}else{returnfalse;}}
Uwaga 1: W systemie Windows nie używaj /Bparametru jak sugerowano gdzie indziej. Zmusza proces do uruchomienia tego samego okna konsoli co startsamo polecenie, co powoduje, że proces jest przetwarzany synchronicznie. Aby uruchomić proces w osobnym wątku (asynchronicznie), nie używaj /B.
Uwaga 2: Puste podwójne cudzysłowy start ""są wymagane, jeśli polecenie jest ścieżką cytowaną. startpolecenie interpretuje pierwszy cytowany parametr jako tytuł okna.
@ Alpha.Dev Testowałem to na Linuksie, ale nie wiem, czy zadziała na innym systemie.
Morfidon
4
Czy potrafisz zorganizować oddzielny proces, a następnie uruchomić kopię w tle? Minęło trochę czasu odkąd zrobiłem PHP, ale funkcja pcntl-fork wygląda obiecująco.
Zauważ, że po uruchomieniu polecenia ta funkcja domyślnie zamyka standardowe wejście i standardowe wyjście uruchomionego procesu. Możesz przekierować dane wyjściowe do jakiegoś pliku za pomocą argumentów $ redirectStdout i $ redirectStderr.
Uwaga dla użytkowników systemu Windows:
Nie można przekierować stdout / stderr nulw następujący sposób:
Możesz wypróbować system kolejkowania, taki jak Resque . Następnie możesz wygenerować zadanie, które przetwarza informacje i dość szybko powraca z obrazem „przetwarzającym”. Dzięki takiemu podejściu nie będziesz wiedział, kiedy zostanie zakończony.
To rozwiązanie jest przeznaczone do zastosowań na większą skalę, gdzie nie chcesz, aby twoje maszyny czołowe wykonywały ciężkie podnoszenie, aby mogły przetwarzać żądania użytkowników. Dlatego może, ale nie musi, pracować z danymi fizycznymi, takimi jak pliki i foldery, ale do przetwarzania bardziej skomplikowanej logiki lub innych zadań asynchronicznych (tj. Nowych wiadomości rejestracyjnych) dobrze jest mieć i jest bardzo skalowalny.
Dzięki tej odpowiedzi : doskonałym narzędziem do uruchomienia procesu w tle byłby Symfony Process Component , który jest oparty na proc_*funkcjach, ale jest o wiele łatwiejszy w użyciu. Więcej informacji znajduje się w jego dokumentacji .
Zamiast inicjować proces w tle, co z tworzeniem pliku wyzwalającego i planowaniem, takim jak cron lub autosys, co jakiś czas wykonuje skrypt, który wyszukuje i działa na pliki wyzwalające? Wyzwalacze mogą zawierać instrukcje lub nawet surowe polecenia (jeszcze lepiej, po prostu uczyń go skryptem powłoki).
W połączeniu z zamknięciem i register_shutdown_function ()
$message ='job executed';
$backgroundJob =function()use($message){//do some work here
echo $message;}
Następnie zarejestruj to zamknięcie, które ma zostać wykonane przed wyłączeniem.
register_shutdown_function($backgroundJob);
Wreszcie, gdy odpowiedź została wysłana do klienta, możesz zamknąć połączenie z klientem i kontynuować pracę z procesem PHP:
fast_cgi_finish_request();
Zamknięcie zostanie wykonane po fast_cgi_finish_request.
Wiadomość $ nie będzie widoczna w żadnym momencie. Możesz zarejestrować tyle zamknięć, ile chcesz, ale zadbaj o czas wykonania skryptu. Działa to tylko wtedy, gdy PHP działa jako moduł Fast CGI (czy to prawda ?!)
Skrypty PHP nie są podobne do innych aplikacji rozwijających język. W językach aplikacji komputerowych możemy ustawić wątki demonów, aby uruchamiały proces w tle, ale w PHP proces występuje, gdy użytkownik żąda strony. Możliwe jest jednak ustawienie zadania w tle za pomocą funkcji zadania cron serwera, którą uruchamia skrypt php.
Ja też zmagałem się z uruchomieniem programu w tle w systemie Windows, podczas gdy skrypt nadal działa. Ta metoda, w przeciwieństwie do innych rozwiązań, pozwala uruchomić dowolny program zminimalizowany, zmaksymalizowany lub bez okna. Rozwiązanie llbra @ phpbrasil działa, ale czasami tworzy niechciane okno na pulpicie, gdy naprawdę chcesz, aby zadanie działało ukryte.
Co należy zrobić, aby uruchomić ten kod? DostajęFatal error: Class 'COM' not found
Alph.Dev
Ps Link do MSDN jest zepsuty
Alph.Dev
@ Alph.Dev: Wygląda na to, że dokument msdn został tymczasowo usunięty. Zawierał więcej przykładów i wyjaśnień dotyczących korzystania z WScript.Shell.
Jimmy Ilenloa
@ Alph.Dev: Dla klasy COM nie znaleziono, to zupełnie inna sprawa. Sprawdź to w Google. Możesz także sprawdzić to php.net/manual/en/com.installation.php
Wiem, że to post ma 100 lat, ale w każdym razie pomyślałem, że może się komuś przydać. Możesz umieścić niewidoczny obraz gdzieś na stronie wskazujący adres URL, który musi być uruchomiony w tle, w następujący sposób:
Odpowiedzi:
Zakładając, że działa na komputerze z systemem Linux, zawsze postępowałem w ten sposób:
Uruchamia to polecenie
$cmd
, przekierowuje dane wyjściowe polecenia$outputfile
i zapisuje identyfikator procesu$pidfile
.To pozwala łatwo monitorować, co robi proces i czy nadal działa.
źródło
Napisz proces jako skrypt po stronie serwera w dowolnym języku (php / bash / perl / etc), a następnie wywołaj go z funkcji kontroli procesu w skrypcie php.
Funkcja prawdopodobnie wykrywa, czy jako strumień wyjściowy zastosowano standardowe io, a jeśli tak, to ustawi wartość zwracaną .. jeśli nie, to kończy się
Przetestowałem to szybko z wiersza poleceń, używając polecenia „sleep 25s” jako polecenia i działało to jak urok.
( Znaleziono odpowiedź tutaj )
źródło
Możesz spróbować dołączyć to do swojego polecenia
na przykład.
źródło
Chciałbym tylko dodać bardzo prosty przykład testowania tej funkcji w systemie Windows:
Utwórz następujące dwa pliki i zapisz je w katalogu internetowym:
foreground.php:
background.php:
Zezwól IUSR na zapis w katalogu, w którym utworzono powyższe pliki
Zezwól IUSR na CZYTANIE I WYKONYWANIE C: \ Windows \ System32 \ cmd.exe
Hit foreground.php z przeglądarki internetowej
Poniższe powinny zostać wyświetlone w przeglądarce z aktualnymi znacznikami czasu i zasobem lokalnym # w tablicy wyjściowej:
Powinieneś zobaczyć testoutput.php w tym samym katalogu, w którym zostały zapisane powyższe pliki, i powinien być pusty
Powinieneś zobaczyć testprocesses.php w tym samym katalogu, w którym zostały zapisane powyższe pliki, i powinien zawierać następujący tekst z aktualnymi znacznikami czasu:
źródło
Jeśli potrzebujesz zrobić coś w tle bez oczekiwania strony PHP na zakończenie, możesz użyć innego (w tle) skryptu PHP, który jest „wywoływany” poleceniem wget. Ten skrypt PHP w tle będzie wykonywany z uprawnieniami, oczywiście, jak każdy inny skrypt PHP w twoim systemie.
Oto przykład systemu Windows używającego wget z pakietów gnuwin32.
Kod w tle (plik test-proc-bg.php) jako przykład ...
Skrypt na pierwszym planie, ten wywołujący ...
Musisz użyć popen / pclose, aby to działało poprawnie.
Opcje wget:
źródło
Oto funkcja umożliwiająca uruchomienie procesu w tle w PHP. W końcu stworzyłem taki, który faktycznie działa również w systemie Windows, po wielu odczytach i testach różnych podejść i parametrów.
Uwaga 1: W systemie Windows nie używaj
/B
parametru jak sugerowano gdzie indziej. Zmusza proces do uruchomienia tego samego okna konsoli costart
samo polecenie, co powoduje, że proces jest przetwarzany synchronicznie. Aby uruchomić proces w osobnym wątku (asynchronicznie), nie używaj/B
.Uwaga 2: Puste podwójne cudzysłowy
start ""
są wymagane, jeśli polecenie jest ścieżką cytowaną.start
polecenie interpretuje pierwszy cytowany parametr jako tytuł okna.źródło
Znalazłem nieco szybszą i łatwiejszą wersję do użycia
i to działa.
źródło
Czy potrafisz zorganizować oddzielny proces, a następnie uruchomić kopię w tle? Minęło trochę czasu odkąd zrobiłem PHP, ale funkcja pcntl-fork wygląda obiecująco.
źródło
Użyj tej funkcji, aby uruchomić program w tle. Jest wieloplatformowy iw pełni konfigurowalny.
Zauważ, że po uruchomieniu polecenia ta funkcja domyślnie zamyka standardowe wejście i standardowe wyjście uruchomionego procesu. Możesz przekierować dane wyjściowe do jakiegoś pliku za pomocą argumentów $ redirectStdout i $ redirectStderr.
Uwaga dla użytkowników systemu Windows:
Nie można przekierować stdout / stderr
nul
w następujący sposób:Możesz to jednak zrobić:
Uwagi dla użytkowników * nix:
1) Użyj polecenia powłoki exec, jeśli chcesz uzyskać rzeczywisty PID:
2) Użyj argumentu $ stdin, jeśli chcesz przekazać niektóre dane do danych wejściowych programu:
źródło
Możesz wypróbować system kolejkowania, taki jak Resque . Następnie możesz wygenerować zadanie, które przetwarza informacje i dość szybko powraca z obrazem „przetwarzającym”. Dzięki takiemu podejściu nie będziesz wiedział, kiedy zostanie zakończony.
To rozwiązanie jest przeznaczone do zastosowań na większą skalę, gdzie nie chcesz, aby twoje maszyny czołowe wykonywały ciężkie podnoszenie, aby mogły przetwarzać żądania użytkowników. Dlatego może, ale nie musi, pracować z danymi fizycznymi, takimi jak pliki i foldery, ale do przetwarzania bardziej skomplikowanej logiki lub innych zadań asynchronicznych (tj. Nowych wiadomości rejestracyjnych) dobrze jest mieć i jest bardzo skalowalny.
źródło
Działające rozwiązanie zarówno dla systemu Windows, jak i Linux. Znajdź więcej na stronie Mój github .
źródło
Dzięki tej odpowiedzi : doskonałym narzędziem do uruchomienia procesu w tle byłby Symfony Process Component , który jest oparty na
proc_*
funkcjach, ale jest o wiele łatwiejszy w użyciu. Więcej informacji znajduje się w jego dokumentacji .źródło
Zamiast inicjować proces w tle, co z tworzeniem pliku wyzwalającego i planowaniem, takim jak cron lub autosys, co jakiś czas wykonuje skrypt, który wyszukuje i działa na pliki wyzwalające? Wyzwalacze mogą zawierać instrukcje lub nawet surowe polecenia (jeszcze lepiej, po prostu uczyń go skryptem powłoki).
źródło
Jeśli używasz PHP, możesz to zrobić o wiele łatwiej, używając pcntl_fork:
http://www.php.net/manual/en/function.pcntl-fork.php
źródło
Mocno używam
fast_cgi_finish_request()
W połączeniu z zamknięciem i register_shutdown_function ()
Następnie zarejestruj to zamknięcie, które ma zostać wykonane przed wyłączeniem.
Wreszcie, gdy odpowiedź została wysłana do klienta, możesz zamknąć połączenie z klientem i kontynuować pracę z procesem PHP:
Zamknięcie zostanie wykonane po fast_cgi_finish_request.
Wiadomość $ nie będzie widoczna w żadnym momencie. Możesz zarejestrować tyle zamknięć, ile chcesz, ale zadbaj o czas wykonania skryptu. Działa to tylko wtedy, gdy PHP działa jako moduł Fast CGI (czy to prawda ?!)
źródło
Skrypty PHP nie są podobne do innych aplikacji rozwijających język. W językach aplikacji komputerowych możemy ustawić wątki demonów, aby uruchamiały proces w tle, ale w PHP proces występuje, gdy użytkownik żąda strony. Możliwe jest jednak ustawienie zadania w tle za pomocą funkcji zadania cron serwera, którą uruchamia skrypt php.
źródło
Dla tych z nas korzystających z systemu Windows spójrz na to:
Odniesienie: http://php.net/manual/en/function.exec.php#43917
uruchom zminimalizowany Notepad.exe w tle:
uruchom polecenie powłoki niewidoczne w tle:
uruchom MSPaint zmaksymalizowany i poczekaj na zamknięcie go przed kontynuowaniem skryptu:
Więcej informacji na temat metody Run () znajduje się na stronie: http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp
Edytowany adres URL:
Przejdź do https://technet.microsoft.com/en-us/library/ee156605.aspx zamiast tego, ponieważ powyższy link już nie istnieje.
źródło
Fatal error: Class 'COM' not found
Wiem, że to post ma 100 lat, ale w każdym razie pomyślałem, że może się komuś przydać. Możesz umieścić niewidoczny obraz gdzieś na stronie wskazujący adres URL, który musi być uruchomiony w tle, w następujący sposób:
<img src="run-in-background.php" border="0" alt="" width="1" height="1" />
źródło