2011-07-07 31 views
4

我必須讓說,2個文件讓說一個index.php等一個included.phpPHP停止包括快速而在實際文件中循環繼續?

的index.php

<?php 
include 'included.php'; 
while(true) 
{ 
    $i++; 
    sleep(3); 
    $o = new tester(); 
} 
?> 

included.php

<?php 
class tester{ 
public function __construct() { 
//execute something 
//wait for lets say one minute without stoping the flow of main loop. 
//Rest code 
} 

?>

我要的是不要在index.php 中停止循環,並且當測試者類被引發執行時e第一部分,然後等我說一分鐘?

可能嗎? 還是我需要別的東西?

+1

「等待...無需停止主循環的流程」可以通過使用過程控制產卵單獨的進程(PHP腳本的實例)。那是你要的嗎?也許是 –

+0

。如果妳能詳細瞭解了有關多一點 – kritya

+1

[fork調用(http://php.net/manual/ru/function.pcntl-fork.php)和pcntl_ *功能,但它不會PHP是工作時用作Apache模塊。注意叉子炸彈。 – sanmai

回答

0

我研究得更多,用我的思想和finnaly我發現辦法我自己,我這樣做:

的index.php

<?php 
$cmd = "php -q nah.php"; 
exec($cmd); 
while (true) 
{ 
sleep(1); 
echo "lalal"; 
} 
?> 

included.php

<?php 
echo "yaya"; 
sleep(3); 
?> 

這是一名魅力

6

你不能用PHP做到這一點。它不是一個多線程語言。您可以通過並行執行PHP的另一個副本來隱約地模擬它,但這不是真正的線程 - 它是兩個完全分離的進程,恰好執行相同的腳本。

在單個PHP實例中,您不能同時執行腳本的兩個或更多不同部分。

+0

我知道它不是一個多線程的語言,但我聽說有一些擴展/國防部 – kritya

+0

非常可疑。向PHP添加線程不會是一個簡單的mod。這根本不是一個線程安全的語言。 –

+0

像管道或任何東西?我需要:( – kritya

1

您可能需要在PHP中查看一些PCNTL functions。我自己沒有太多的經驗,但前段時間偶然發現了它。這不是真的以任何方式進行線程,但可能會使你更接近你想要達到的效果。

此外,如果您有PHPClasses帳戶,我找到的鏈接可能與您有關:a PHP PCNTL wrapper class

+0

那麼我找不到一個好辦法,我如何從phpclasses執行任何東西,如果你有一些經驗? – kritya

+0

我沒有任何經驗與這個特殊的類,但似乎有一些例子在該頁面上的使用下載 – theotherlight

2

您可以編寫一個新腳本testerStart.php,您可以通過url訪問該腳本。這樣,你實際上調用服務器上的另一個腳本,它將獨立於你的腳本腳本運行。

所以index.php文件看起來像:

<?php 
    while(true) 
    { 
    $i++; 
    sleep(3); 
    // call testerStart.php asynch 
    } 
?> 

testerStart.php會是什麼樣子:

<?php 
    include 'included.php'; 
    $o = new tester(); 
?> 
+0

但是打電話它使用一個URL可以導致文件serous漏洞.... – kritya

+0

嗯。你將不得不確保你是唯一能夠調用這個文件的人。這樣做的可能方法是生成一些存儲在服務器上的密鑰,只有調用者和被調用的腳本知道該腳本,腳本只有在提供了正確的密鑰時纔會執行。或者你可以配置服務器,只有本地主機才能訪問testerStart腳本。 – pintxo

+0

如何獲得該密鑰? – kritya

1

我不知道,但你可以嘗試像

<?php 
include 'included.php'; 
$instances = array(); 
while(true) 
{ 
    foreach ($instances as $key => $instance) { 
     if ($result = stream_get_contents($instance)) { 
      pclose($instance); 
      unset($instances[$key]); 
      $o = unserialize($result); 
      // do something with the object 
     } 
    } 
    $instances[] = popen('php /path/to/include.php', 'r'); 
} 
?> 


<!-- in include.php --> 
<?php 
include 'included.php'; 
echo serialize(new tester()); 
?> 

或者你可以將所有的邏輯爲「include.php」所以主腳本不關心結果的一切,你將需要返回主要腳本知道它可能會關閉進程句柄。

在這裏,我們在推出單獨的進程腳本與popen('php /path/to/include.php', 'r');,並得到一個可讀的管給它(這樣我們就可以讀了什麼過程輸出)。當在單獨的過程被成功地創建的對象,我們序列化並輸出結果。回到每個迭代的主腳本中,我們檢查已經打開的實例,如果它們中的一些返回某些內容 - 我們將這些內容視爲序列化對象,將其反序列化,然後使用它處理任何我們想要的內容;那麼在完成我們想要的任務後,我們關閉該進程並將其從打開的實例列表中刪除。其實,如果在你的代碼while(true)並沒有真正運行下去,而是直到某些條件得到滿足 - 這將是加工環節轉移到不同的週期,在初始化之後是一個好主意......就像

while($condition) 
{ 
    $instances[] = popen('php /path/to/include.php', 'r'); 
} 
while (!empty($instances)) { 
    foreach ($instances as $key => $instance) { 
     if ($result = stream_get_contents($instance)) { 
      pclose($instance); 
      unset($instances[$key]); 
      $o = unserialize($result); 
      // do something with the object 
     } 
    } 
} 
+0

給我一個錯誤 – kritya

+2

嗯......「你好,它給了我一些錯誤」 - 「嘗試一下」。錯誤說的是什麼? – Slava

+0

給我一個錯誤類沒找到,當我沒有把類。 – kritya

4

這個問題是非常普遍的,但我不認爲這是使用PHP的正確方法...... usuaily php試圖儘快執行的事情,例如渲染網頁。如果你想添加時間和動態的東西,那麼每次你想要執行腳本時都需要發送單個請求到服務器。

或許CRONJOBS或AJAX會更適合你正在嘗試做的。

+0

我正在使用CLI。在這裏可以使用cron作業嗎? =。= – kritya

+0

可以使用Cron作業在特定時間完成任務。無論你的任務需要在一定的時間間隔內完成,cronjob也可以在一定的時間間隔內完成。 –

0

你確實需要一個更復雜的設置。

您確實想看看前面已經提到了pcntl功能,雖然這些都只是使用CLI時建議。當您通過Apache的Web應用程序需要它時,您需要查看其他解決方案,因爲分叉您的流程將無法正常工作。

上述popen等其他解決方案是另一個很好的解決方案,雖然它可能會使您的代碼依賴於您的架構(unix上的路徑與windows上的路徑不同,您需要確定'php'是可調用的, ...)

如果上述兩種可能性都沒有選擇,我建議做使用異步HTTP請求或者捲曲與stream_set_blocking禁用的fsockopen。 這將是一個相當大量的工作,但是,但是異步調用將獲得後臺腳本運行和您的父母腳本可以簡單地繼續。然後在父進程的循環中,偶爾檢查你的後臺腳本是否已經完成 - 用fsockopen:stream_get_contents($ resource)直到feof($ resource)