重新装入类

2022-08-24 00:00:00 class oop daemon php

我有一个在命令行上运行的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的一部分,它会查看模块的文件时间,确定它是否更改了,如果更改了,则有效地重新加载类。

这就是问题所在,很明显,如果我再次包含类文件,它将出错,因为类已经存在。

到目前为止,我所有关于如何解决这个问题的想法都是病态的,我想避免这样做。

到目前为止,我有几个潜在的解决方案,但我对它们都不满意。

  1. 更新模块时,将其置于新的命名空间中,并将引用指向该命名空间

    我不喜欢这个选项,也不确定是否可以这样做(好像我是对的,命名空间必须在文件的顶部定义?这绝对可以使用FILE_GET_CONTENTS()解决,但我希望避免)

  2. 分析PHP文件,然后使用runkit-方法-重定义重新定义所有方法。

    任何涉及这种分析的事情都是糟糕的计划。

  3. 不包括该文件,而是复制该文件,所有内容都相同,但str_将类名替换为末尾带有rand()或类似的内容以使其唯一。

对于如何a)解决此问题或b)重组模块系统以避免此问题发生,有谁有更好的想法吗?

我们非常欢迎任何建议/想法/建设性的批评!


解决方案

您可能应该在分叉进程中按需加载文件。

您会收到一个请求 =>派生主进程,包括模块并运行它。

这还允许您一次运行多个命令,而不必等待每个命令运行后再启动下一个命令。

php中的Fork: http://php.net/manual/en/function.pcntl-fork.php

相关文章