我在命令行上运行了一个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的一部分,它会查看模块的filemtime,如果它被更改则计算出来,如果是,则有效地重新加载类。
这就是问题出现的地方,显然如果我再次包含类文件,它就会因为类已经存在而出错。
到目前为止,我对如何解决这个问题的所有想法都非常恶心,我想避免这样做。
到目前为止,我有一些可能的解决方案,但我对其中没有一个感到满意。
当模块更新时,将其置于新的命名空间中并将引用指向
我不喜欢这个选项,也不确定它是否可以完成(好像我是对的,名称空间必须在文件顶部定义?这绝对可以解决file_get_contents(),但是我“我宁愿避免它”
解析PHP文件,然后使用runkit-method-redefine重新定义所有方法。
涉及这种解析的任何事情都是一个糟糕的计划。
不要包含文件,而是使用相同的内容制作文件的副本,但是将类名str_replacing到最后使用rand()或类似的东西,以使其唯一。
有没有人对如何a)解决这个问题或者b)重组模块系统有更好的想法,所以不会出现这个问题?
非常欢迎任何建议/想法/建设性批评!
答案 0 :(得分:1)
您应该在分叉的过程中按需加载文件。
您收到了请求 => fork主进程,包含模块并运行它。
这也允许您一次运行多个命令,而不必在启动下一个命令之前等待每个命令运行。
答案 1 :(得分:0)
如果模块使用外部类(在命名空间中具有相对路径),则使用命名空间的技巧将失败。 解析伎俩是非常危险的 - 如果模块应该保持状态怎么办?如果不仅仅改变了方法,而且例如实现了接口的名称,该怎么办?如果它们链接到重载类的实例,它将如何影响其他对象?
我认为@Kethryweryn是你可以尝试的东西。