6

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

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

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

例如,我计划创建一个main.php文件,user.php其中包含包含 classMyUsergame.php包含 class的文件MyGame现在假设我想对服务器进行更改user.php并“重新加载”服务器,以便更改user.php生效,而不断开任何在线用户?

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

更新

我自己的解决方案是:

  1. 在特殊情况下,包含文件 external.php,它可以访问一些变量并根据需要使用它们。这样做时,我必须确保代码中没有错误,因为如果我尝试访问不存在的方法,整个服务器将会崩溃。
  2. 将整个事情重写为 Java,这使我有可能使用动态类重新加载来添加插件系统。奇迹般有效。再见 PHP。
4

7 回答 7

8

难道不用重新启动整个脚本就可以对php源进行更改吗?

[...]

我计划拥有一个包含 user.php 的 main.php 文件,其中包含 MyUser 类

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

于 2012-06-05T20:54:19.060 回答
2

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

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

于 2012-06-05T20:55:36.417 回答
2

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

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

于 2012-06-05T21:04:06.477 回答
0

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

于 2012-06-05T21:07:45.407 回答
0

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

要在缓存中包含函数,您必须包含SuperClosure 类。一个例子是:

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 的教程,请参见此处

于 2012-06-05T21:18:56.190 回答
0

简单的解决方案使用 $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

于 2015-07-25T05:11:07.797 回答
-1

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

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

于 2012-06-05T20:57:08.747 回答