重新加载课程

时间:2013-09-13 13:07:51

标签: php class oop daemon

我在命令行上运行了一个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,如果它被更改则计算出来,如果是,则有效地重新加载类。

这就是问题出现的地方,显然如果我再次包含类文件,它就会因为类已经存在而出错。

到目前为止,我对如何解决这个问题的所有想法都非常恶心,我想避免这样做。

到目前为止,我有一些可能的解决方案,但我对其中没有一个感到满意。

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

    我不喜欢这个选项,也不确定它是否可以完成(好像我是对的,名称空间必须在文件顶部定义?这绝对可以解决file_get_contents(),但是我“我宁愿避免它”

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

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

  3. 不要包含文件,而是使用相同的内容制作文件的副本,但是将类名str_replacing到最后使用rand()或类似的东西,以使其唯一。

  4. 有没有人对如何a)解决这个问题或者b)重组模块系统有更好的想法,所以不会出现这个问题?

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

2 个答案:

答案 0 :(得分:1)

您应该在分叉的过程中按需加载文件。

您收到了请求 => fork主进程,包含模块并运行它。

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

在PHP中分叉: http://php.net/manual/en/function.pcntl-fork.php

答案 1 :(得分:0)

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

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