是否可以在脚本运行时动态重新加载 PHP 代码


Is it possible to dynamically reload PHP code while script is running?

我有一个使用PHPSockets的多人游戏服务器,因此完全是用PHP编写的。

目前,每当我对PHP服务器脚本进行任何更改时,我都必须终止脚本,然后重新启动它。这意味着任何在线用户都是断开连接的(通常不是问题,因为目前没有那么多)。

现在我正在重写服务器脚本以使用自定义PHP类并稍微整理一下(您不想知道它今天看起来有多讨厌)。今天我在想:"难道不应该在不重新启动整个脚本的情况下对 php 源代码进行更改吗?

例如,我计划有一个main.php包含类MyUser user.php和包含类MyGamegame.php文件。现在假设我想对user.php进行更改并"重新加载"服务器,以便对user.php所做的更改生效,而不会断开任何在线用户的连接?

试图找到其他问题来回答这个问题,我得到的最接近的是这个问题:修改正在运行的脚本并让它重新加载而不杀死它 (php) ,但这似乎并不能解决在线用户的断开连接问题。

更新

我自己的解决方案是:

  1. 在特殊情况下,包括文件external.php,它可以访问一些变量并根据需要使用它们。执行此操作时,我必须确保代码中没有错误,因为如果我尝试访问不存在的方法,整个服务器都会崩溃。
  2. 将整个内容重写为 Java,这使我可以使用动态类重新加载添加插件系统。就像一个魅力。再见PHP。

不应该可以在不重新启动整个脚本的情况下对 php 源代码进行更改吗?

[...]

我打算有一个包含用户的主文件.php.php 包含类 MyUser

在你的情况下,你不能。类只能在正在运行的脚本中定义一次。您需要重新启动脚本才能重新定义这些类。

我对PHP不太熟悉,但我假设创建了一个进程来运行脚本,这样做它会复制运行程序所需的指令并开始在CPU上执行,在此期间,如果您要"更新"指令,则需要终止进程最终并重新启动它。包含是一种将类和文件链接在一起的奇特方式,但最终处理器会将该信息与存储它们的文件的位置分开,并且在您重新启动该过程之前最终会有所不同。

我不知道有任何系统可以创建代码并主动编辑它并在运行代码时查看更改。大多数活动程序都需要重新启动才能重新加载新的源代码。

Runkit 将允许您在运行时添加、删除和重新定义方法(以及其他内容)。虽然不能更改类或其现有实例的已定义属性,但它允许您更改这些对象的行为。

我不建议将其作为永久解决方案,但它在开发过程中可能很有用。最终,您需要将游戏状态存储到文件,数据库,Memcache等中。

如何将您的 User 对象存储到 APC 缓存中,同时您的主脚本从缓存加载并经常检查新的操作码。

若要在缓存中包含函数,必须包含超级闭包类。一个例子是:

if (!apc_exists('area')) {
  // simple closure
  // calculates area given length and width
  $area = new SuperClosure(
    function($length, $width) {
      return $length * $width;
    }
  );
  apc_store('area', $area);
  echo 'Added closure to cache.';
} else {
  $func = apc_fetch('area');
  echo 'Retrieved closure from cache. ';
  echo 'The area of a 6x5 polygon is: ' . $func(6,5);
}

有关 APC 的教程,请参见此处。

简单的解决方案 使用 $MyUser 而不是 MyUser

require MyUserV1.php;
$MyUser = 'MyUserV1';
$oldUser = new $MyUser('your name');
//Some time after
require MyUserV2.php;
$MyUser = 'MyUserV2';
$newUser = new $MyUser('your name');

每个声明的类都保留在内存中,但在最后一次 MyUserV1 注销
时变为未使用你可以让它们继承自抽象类MyUser,以便使用is_a

您不能再次include具有相同class的文件,但您可以使用array 来执行此操作。您也可以 从array转换为class ,如果您确实需要这样做。但是,这仅适用于数据,不适用于行为(方法)。

我对PC上的游戏不太了解这些东西,但是您可以尝试从数据库中为用户获取所有变量,然后使用这些变量更新文本字段或按钮

在web中使用AJAX(在不刷新页面的情况下更改数据)。不是用于编程的吗?