重新装入类
我有一个在命令行上运行的PHP守护程序脚本,可以通过telnet等连接到该脚本并接受命令。
它对该命令的处理基于加载的模块,这是当前在开始时完成的。(为简洁起见,请参见下面的伪代码)
$modules = LoadModules();
StartConnection();
while(true){
ListenForCommands();
}
function LoadModules(){
$modules = Array();
$dir = scandir("modules");
foreach($dir as $folder){
include("modules/".$folder."/".$folder.".php");
$modules[$folder] = new $folder;
}
}
function ListenForCommands(){
if(($command = GetData())!==false){
if(isset($modules[$command])){
$modules[$command]->run();
}
}
}
因此,一个名为"bustime"的示例模块将是一个名为bustime的类,它位于/MODULES/Bustime/bustimes.php
这工作得很好。但是,我想让它可以动态更新模块,这样作为ListenForCommands的一部分,它会查看模块的文件时间,确定它是否更改了,如果更改了,则有效地重新加载类。
这就是问题所在,很明显,如果我再次包含类文件,它将出错,因为类已经存在。
到目前为止,我所有关于如何解决这个问题的想法都是病态的,我想避免这样做。
到目前为止,我有几个潜在的解决方案,但我对它们都不满意。
更新模块时,将其置于新的命名空间中,并将引用指向该命名空间
我不喜欢这个选项,也不确定是否可以这样做(好像我是对的,命名空间必须在文件的顶部定义?这绝对可以使用FILE_GET_CONTENTS()解决,但我希望避免)分析PHP文件,然后使用runkit-方法-重定义重新定义所有方法。
任何涉及这种分析的事情都是糟糕的计划。
不包括该文件,而是复制该文件,所有内容都相同,但str_将类名替换为末尾带有rand()或类似的内容以使其唯一。
对于如何a)解决此问题或b)重组模块系统以避免此问题发生,有谁有更好的想法吗?
我们非常欢迎任何建议/想法/建设性的批评!
解决方案
您可能应该在分叉进程中按需加载文件。
您会收到一个请求 =>派生主进程,包括模块并运行它。这还允许您一次运行多个命令,而不必等待每个命令运行后再启动下一个命令。
php中的Fork: http://php.net/manual/en/function.pcntl-fork.php
相关文章