2010-03-16 48 views
13

我們在Windows服務器上運行PHP(確實存在許多問題的源代碼,但遷移目前不是選項)。有幾點,用戶發起的操作需要啓動一些需要一段時間的事情,而用戶不需要知道它們是成功還是失敗,例如發送電子郵件或確保某些內容第三方帳戶已更新。如果我可以用pcntl_fork()分叉,這將非常簡單,但PCNTL函數在Windows中不可用。在Windows上使用PHP分叉

看來我可以得到最接近的是做這種性質的東西:

exec('php-cgi.exe somescript.php'); 

然而,這將是複雜得多。我需要啓動的操作依賴於運行過程中已經存在的很多上下文;要使用上面的例子,我需要弄清楚基本數據並以某種方式將其提供給新腳本。如果我可以分叉,這只是讓父程序早日返回,讓孩子在更多的事情上工作的問題。

我發現有幾個人在談論他們自己的工作以獲得在Windows上編譯的各種PCNTL函數,但似乎沒有任何可用的東西(斷開的鏈接等)。

儘管this question與我的名字實際上是相同的,但似乎問題是執行超時比需要fork更多。那麼,我最好的選擇是重構一下來處理調用php-cgi,還是有其他選擇?

編輯:看起來exec()不會爲此工作,至少不是沒有我找出它的一些其他方面,因爲它等待,直到電話回來。我想我可以使用START,有點像exec('start php-cgi.exe somescript.php');,但它仍然在等待,直到其他腳本完成。

+0

你認爲這是一個cron工作嗎? (有一些可用的選項,http://www.google.com/search?q = cron + windows) – user187291 2010-03-16 21:27:07

+0

從我所看到的情況來看,它看起來像使用psexec一樣正常,但我只是用psexec得到了一些東西,所以我可能會堅持這一點。 – 2010-03-17 16:36:38

回答

13

怎麼樣installing psexec和使用-d(不等待)option

exec('psexec -d php-cgi.exe somescript.php'); 
+0

非常好,我得到了那個工作。我爲什麼用'start'執行不能完成我所需要的工作而困惑不解。另外,我需要使用-accepteula參數調用psexec,即使我已經手動接受它自己在服務器上運行它。 – 2010-03-17 16:35:31

+0

如果你正在尋找一種方法來傳遞變量,然後使用這個'exec(「psexec -d php -cgi.exe somescript.php'var1''var2''var3'」);'然後在php腳本中,重新發送變量,使用'$ argv [1]','$ argv [2]'和'$ argv [3]'。 – 2014-05-08 17:59:23

3

獲取PSExec並運行命令:

exec("psexec -d php-cgi.exe myfile.php"); 
+2

以及這個答案確實有一個鏈接,但其他沒有 – SeanDowney 2011-07-11 22:09:51

1

您可以創建一個後臺程序/後臺進程運行代碼(例如發送電子郵件),並且請求只需要將項目添加到隊列中,讓deamon完成繁重的工作。

例如,文件send_emails.bat

cls 
C:\PHP533\php.exe D:\web\server.php 
exit 

打開Windows任務調度程序,以及具有上述send_emails.bat開始,每隔30分鐘。確保一次只運行一個實例,或者可以以多個運行每個任務,或者每次發送兩封電子郵件。我說30分鐘以防萬一暫時中斷(內存問題,數據庫不可用等),它將每30分鐘重新啓動一次,而不是停止一個永不停止的進程。以下是骨架守護......不完全或測試我只是打字的例子:

<?php 
set_time_limit(60*30); // don't run 
$keepgoing = true; 
$timeout = time()+ 60*29; // 29 minutes 

while(time() < $timeout) 
{ 
    // grab emails from database 
    $result = $db->query('select subject, body, to_email FROM email_queue'); 
    if($result->num_rows == 0) 
    { 
     sleep(10); // so we are not taxing the database 
    } 
    else 
    { 
     while($row = $result->fetch_assoc()) 
     { 
     // send email 
     } 
    } 
} 
exit; 
?> 

最後你只需要請求給項目添加到隊列在數據庫中,並讓守護進程句柄沉重的舉重。

$db->query('insert into email_queue(to,subject,body) values ('[email protected]','important email','<b>html body!</b>');