我正在研究一個PHP IRC Bot,我目前正在研究這些命令。有沒有辦法使用PHP「取消」一個文件?
在main.php
開頭的腳本中,它包含class_lib.php
文件並實例化該類的對象。我想處理一個!reload
命令,它將「取消」該文件,然後重新包括它。這是可能的,還是會沒事的,如果我只是include
當它再次發送該命令?
編輯:基本上,我希望能夠修改並重新加載類,而無需重新啓動機器人。
我正在研究一個PHP IRC Bot,我目前正在研究這些命令。有沒有辦法使用PHP「取消」一個文件?
在main.php
開頭的腳本中,它包含class_lib.php
文件並實例化該類的對象。我想處理一個!reload
命令,它將「取消」該文件,然後重新包括它。這是可能的,還是會沒事的,如果我只是include
當它再次發送該命令?
編輯:基本上,我希望能夠修改並重新加載類,而無需重新啓動機器人。
爲什麼不只是允許對象重新加載默認設置或重新啓動,而不是您描述的內容?無論如何,我很肯定你不能那樣做。
另外,不要嘗試用class_lib.php加載對象。將類文件包含在對象中,然後在需要的地方和時間創建對象。這樣你可以停止它,銷燬對象,然後重新實例化另一個對象,這應該完成你想要的。
我不確定如何銷燬對象 – Rob
未設置($ objectvar)。 http://php.net/manual/en/function.unset.php –
如果你正在銷燬一個創建了數據庫連接或其他有開放資源的活動的對象,你還應該創建一個$ objectvar- >對象類中的destroy()函數關閉所有資源,保存任何需要保存的內容,然後取消設置($ objectvar)。 –
恐怕沒有辦法取消包含文件。如果它是一個函數,您可以每次動態生成一個新函數。
檢查:
http://php.net/manual/en/function.create-function.php
您可以將功能分配給一個變量,然後明確表示變量,並再次分配給它。
晚答案..
您可以創建一個包含文件,然後的eval數組(的file_get_contents($文件名))
我一直工作在一個名爲PITC我自己的IRC客戶端,並可能我可能會使用的方法,這是我之前做的東西
哦,'eval'的奇蹟。順便說一句,這很諷刺。包含$ filename的 –
完全一樣。 – AbiusX
這個問題本質上是關於在php中開發動態加載的php插件,它不會對其他插件或主代碼造成干擾。
我知道的唯一方法是需要重新設計原始的class_lib.php並創建一個'Plugin'類,它將充當代理類,在每個函數/方法調用時執行一個新的php實例並傳遞帶有json_decode調用的函數參數,然後用json_encode回顯響應。
function proxyExternalFunction($fileName, $functionName, $args, $setupStatements = '') {
$output = array();
$command = $setupStatements.";include('".addslashes($fileName)."');echo json_encode(".$functionName."(";
foreach ($args as $arg) {
$command .= "json_decode('".json_encode($arg)."',true),";
}
if (count($args) > 0) {
$command[strlen($command)-1] = ")";//end of $functionName
}
$command .= ");";//end of json_encode
$command = "php -r ".escapeshellarg($command);
exec($command, $output);
$output = json_decode($output,true);
}
這將不得不做了通過代理類每一個函數/方法調用......沒有那麼高效,它永遠不會爲堅持資源或其他不可序列化的變量引用的對象/關聯數組工作引用。
另一個更有效的選項是http://www.php.net/runkit,它允許您與長時間運行的嵌入式php實例進行交互。
遲到了,但我不得不提到以下PHP擴展:
http://www.php.net/manual/en/book.runkit.php
的runkit擴展提供手段來修改常量,用戶定義的函數,和用戶定義的類。它還通過沙盒提供了自定義超全局變量和可嵌入的子解釋器。
這將允許您重新定義類,解析包含的文件時發生。
注意:我沒有使用過這個,在研究了它是否有可能以某種方式熱切換某些類之後,我找到了它。我無法保證安全,不能提供動手信息。然而。
你應該解釋你正在努力完成什麼,或者更具體的原因。您可以通過卸載並重新加載類定義來重新實例化對象。 – mario
重新加載腳本嗎? – Rob
爲什麼「新的MyClass()」實例不起作用? – lepe