Php 重新加载类

Php 重新加载类,php,class,oop,daemon,Php,Class,Oop,Daemon,我在命令行上运行了一个PHP守护程序脚本,可以通过telnet等连接到该脚本,并可以向其发送命令 它对命令所做的操作基于加载的模块,这是当前在开始时完成的。(为简洁起见,请参见下面的psuedocode) 因此,一个名为“bastimes”的示例模块将是一个名为bastimes的类,位于/modules/bastimes/bastimes.php中 这个很好用。但是,我想使其能够动态更新模块,因此作为ListenForCommands的一部分,它可以查看模块的filemtime,确定它是否已更改

我在命令行上运行了一个PHP守护程序脚本,可以通过telnet等连接到该脚本,并可以向其发送命令

它对命令所做的操作基于加载的模块,这是当前在开始时完成的。(为简洁起见,请参见下面的psuedocode)

因此,一个名为“bastimes”的示例模块将是一个名为bastimes的类,位于/modules/bastimes/bastimes.php中

这个很好用。但是,我想使其能够动态更新模块,因此作为ListenForCommands的一部分,它可以查看模块的filemtime,确定它是否已更改,如果已更改,则可以有效地重新加载类

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

到目前为止,我所有关于如何绕过这个问题的想法都很糟糕,我希望避免这样做

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

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

    我不喜欢这个选项,也不确定它是否可以实现(好像我是对的,名称空间必须定义在文件的顶部?对于文件\u get\u contents(),这肯定是可以解决的,但我宁愿避免)

  • 解析PHP文件,然后使用runkit方法redefine来重新定义所有方法

    任何涉及这种解析的事情都是一个糟糕的计划

  • 不包括该文件,而是制作一个文件副本,所有内容都相同,但str_会将类名替换为末尾带有rand()或类似名称的内容,以使其唯一

  • 有没有人对如何a)绕过这个问题或b)重组模块系统以避免出现这个问题有更好的想法


    任何建议/想法/建设性批评都将非常受欢迎

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

    你收到一个请求 =>分叉主进程,包括模块并运行它

    这还允许您一次运行多个命令,而不必在启动下一个命令之前等待每个命令的运行

    php中的Fork:

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

    你收到一个请求 =>分叉主进程,包括模块并运行它

    这还允许您一次运行多个命令,而不必在启动下一个命令之前等待每个命令的运行

    php中的Fork:

    如果模块使用外部类(在名称空间中具有相对路径),则使用名称空间的技巧将失败。 解析的技巧是非常危险的——若模块应该保持状态呢?若不仅改变了方法,而且还改变了实现接口的名称,那个该怎么办?若其他对象链接到重新加载的类的实例,它将如何影响它们


    我认为@Kethryweryn是可以尝试的。

    如果模块使用外部类(在名称空间中有相对路径),那么使用名称空间的技巧将失败。 解析的技巧是非常危险的——若模块应该保持状态呢?若不仅改变了方法,而且还改变了实现接口的名称,那个该怎么办?若其他对象链接到重新加载的类的实例,它将如何影响它们


    我认为@Kethryweryn是你可以尝试的东西。

    今晚我会尝试一下,看看它的效果如何,谢谢你=]如果你遇到麻烦,请不要犹豫寻求更多帮助,fork一开始可能有点令人畏惧。我今晚会尝试一下,看看它的效果如何,谢谢你=]如果你遇到麻烦,不要犹豫寻求更多的帮助,一开始你可能会有点畏缩。
    $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();
        }
      }
    }