2010-11-19 62 views
1

我遇到了IRC Bot腳本的問題,我已將它實現到了我的Curl轉移方法中。PHP - IRC Bot腳本掛起

我有一個問題,一旦IRC機器人向IRC頻道發送消息,腳本末尾的所有「回顯」都不會顯示,並且頁面掛起。整個Apache掛起。

<?php 

$ircServer = "///"; 
$ircPort = "6667"; 
$ircChannel = "#bots"; 

set_time_limit(0); 

$msg = $_POST['msg']; 
$paper = $_POST['paper']; 
$sizzor = $_POST['sizzor']; 
$hand = $_POST['hand']; 

$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS); 

if ($ircSocket) 
{ 

    fwrite($ircSocket, "USER Lost rawr.test lol :code\n"); 
    fwrite($ircSocket, "NICK Rawr" . rand() . "\n"); 
    fwrite($ircSocket, "JOIN " . $ircChannel . "\n"); 

ignore_user_abort(TRUE); // Noob Close down page 

    fwrite($ircSocket, "PRIVMSG " . $ircChannel . " :" . $msg . "\n"); 

    while(1) 
    { 
     while($data = fgets($ircSocket, 128)) 
     { 
      echo nl2br($data); 
      flush(); 

      // Separate all data 
      $exData = explode(' ', $data); 

      // Send PONG back to the server 
      if($exData[0] == "PING") 
      { 
       fwrite($ircSocket, "PONG ".$exData[1]."\n"); 
      } 
} 
    echo $eS . ": " . $eN; 
} 
} 
?> 
if ($bootcontents == 'success') {  
echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 

這部分不腳本中顯示:

if ($bootcontents == 'success') { 
    echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 

頁面只是掛起,如果我添加了exit();功能上接近頂部整個「回聲」信息不顯示。

請有人幫忙。

+0

我看到你有一個循環:while(1)。如果你沒有終止條件來打破這個循環,它將是一個無限循環。 – ryanlahue 2010-11-19 22:39:25

+3

通過網絡服務器啓動這樣的東西是不好的。此外,理智的服務器不會讓你的機器人發送任何消息,因爲它不響應可能在收到USER和NICK後立即發送的PING。 – ThiefMaster 2010-11-19 22:43:52

+0

您必須從命令行運行您的bot,而不是通過網頁。 – Jocelyn 2012-06-05 21:37:47

回答

0

你正在創建一個無限循環:

while (1) 
// ... 

這個循環可以寫不完,因爲你沒有使用EXIT指令(如break)。因此無限循環後的代碼永遠不會執行。 此外,它是一個繁忙的循環(使用大量的CPU資源),所以整個Apache(和計算機)將掛起。

+0

爲什麼是-1?答案應該是正確的(?) – apfelbox 2012-08-06 23:03:56

+0

該腳本旨在無限運行,即通過設計。可能這就是爲什麼你會看到downvote。從代碼中可以明顯看出這是有意的。當然,給出的解釋是OP失敗的一部分。所以你得到反對票。 – hakre 2012-08-13 11:03:08

+0

hakre ... OP的目的是要有一個無限循環來捕捉服務器輸出,但他的設計是完全錯誤的......並回答OP爲什麼回聲從未運行與上述2回覆的問題完全有效,因爲他從來沒有問過關於他的設計,但爲什麼這部分代碼不起作用。所以我們可以忽略他的設計意圖,並對代碼本身發表評論。 – Populus 2012-10-14 23:48:28

0

您正在從<?php ?>標記中刪除一些標記,因此無論外界的標記都將被視爲純文本。你修復它移動結束?>標籤進一步下跌:

 [this is the while(1) closing bracket] 
     } 
    // code past this line will never run, see below for details 
    echo $eS . ": " . $eN; 
    } 
} 
if ($bootcontents == 'success') { 
    echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 
} 
?> <!-- closing tag goes here --> 

該網頁將反正不能正確,因爲while(1)環缺少退出條件工作

while(1) { 
    while($data = fgets($ircSocket, 128)) { 
     // ... 
    } 
} 

while完成後,你的腳本不斷循環,最終陷入一個空的無限循環(如果它沒有配置爲檢測並消除這種漏洞,它將掛起服務器)。

在最後的通知中,PHP並不是最適合這項工作的工具:使用獨立應用程序可能會更好。

0
while($data = fgets($ircSocket, 128)) 

這部分阻止腳本運行,直到它接收到的數據,如果不知何故你不通過該套接字獲取數據...好你被困在那裏...永遠...哈哈OK,卡住直到PHP腳本超時。

如果這部分沒有捕獲,你仍然被困在while循環中,所以沒有辦法運行你的代碼的那部分回聲消除......所以apfelbox和Alex都是正確的,只是沒有完全解釋...

爲了有一個無限循環,但也能夠在外面運行代碼,你需要捕捉你想捕獲和運行代碼的「事件」。你想要捕獲的所有事件都需要在while循環中,或者至少從while循環分派到一個函數,該函數可以解析來自服務器的輸入並正確響應。

更好的方法是利用觀察者模式。

即使通過命令行運行它,我也不會用PHP創建IRC bot。PHP並不意味着作爲一個長期運行的應用程序運行。