我有一个在命令行上运行的 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();
}
}
}
因此,一个名为“bustimes”的示例模块将是一个名为 bustimes 的类,位于 /modules/bustimes/bustimes.php
这工作正常。但是,我想让它可以即时更新模块,因此作为 ListenForCommands 的一部分,它会查看模块的文件时间,确定它是否已更改,如果是,则有效地重新加载该类。
这就是问题所在,显然如果我再次包含类文件,它会出错,因为类已经存在。
到目前为止,我对如何解决这个问题的所有想法都很恶心,我想避免这样做。
到目前为止,我有一些潜在的解决方案,但我对它们都不满意。
当模块更新时,将其放在新的命名空间中并将引用指向那里
我不喜欢这个选项,我也不确定它是否可以完成(好像我是对的,命名空间必须在文件顶部定义?这绝对可以使用 file_get_contents() 解决,但我更喜欢避免它)
解析 PHP 文件,然后使用 runkit-method-redefine 重新定义所有方法。
任何涉及这种解析的事情都是一个糟糕的计划。
不要包含该文件,而是使用相同的所有内容制作文件的副本,但将 str_replace 类名替换为末尾带有 rand() 或类似名称的内容以使其唯一。
是否有人对如何 a) 解决此问题或 b) 重组模块系统以使此问题不发生有任何更好的想法?
非常欢迎任何建议/想法/建设性批评!