Is it possible to dynamically reload PHP code whil

2019-06-18 11:04发布

I'm having a multiplayer server that's using PHPSockets, and thus is written entirely in PHP.

Currently, whenever I'm making any changes to the PHP server-script I have to kill the script and then start it over again. This means that any users online is disconnected (normally not a problem because there aren't so many at the moment).

Now I am rewriting the server-script to use custom PHP classes and sorten things up a little bit (you don't want to know how nasty it looks today). Today I was thinking: "Shouldn't it be possible to make changes to the php source without having to restart the whole script?".

For example, I'm planning on having a main.php file that is including user.php which contains the class MyUser and game.php which contains the class MyGame. Now let's say that I would like to make a change to user.php and "reload" the server so that the changes to user.php goes into effect, without disconnecting any online users?

I tried to find other questions that answered this, the closest I got is this question: Modifying a running script and having it reload without killing it (php) , which however doesn't seem to solve the disconnection of online users.

UPDATE

My own solutions to this were:

  1. At special occations, include the file external.php, which can access a few variables and use them however it'd like. When doing this, I had to make sure that there were no errors in the code as the whole server would crash if I tried accessing a method that did not exist.
  2. Rewrite the whole thing to Java, which gave me the possibility of adding a plugin system using dynamic class reloading. Works like a charm. Bye bye PHP.

7条回答
虎瘦雄心在
2楼-- · 2019-06-18 11:16

I am not too familiar with PHP but I would assume that a process is created to run the script, in doing so it copies the instructions needed to run the program and begins execution on the CPU, during this, if you were to "update" the instructions, you'd need to kill the process ultimate and restart it. Includes are a fancy way of linking your classes and files together but ultimately the processor will have that information separate from where the file of them are stored and it is ultimately different until you restart the process.

I do not know of any system in which you can create code and actively edit it and see the changes while that code is being run. Most active programs require restart to reload new source code.

查看更多
我命由我不由天
3楼-- · 2019-06-18 11:16

Simple solution use $MyUser instead of MyUser

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

Every declared class stay in memory but become unused when the last MyUserV1 logout
you can make them inherit from an abstract class MyUser for using is_a

查看更多
放荡不羁爱自由
4楼-- · 2019-06-18 11:17

How about storing your User object into APC cache while your main script loads from the cache and checks every so often for new opcode.

To include a function in the cache, you must include the SuperClosure Class. An example would be:

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);
}

See here for a tutorial on APC.

查看更多
淡お忘
5楼-- · 2019-06-18 11:23

Shouldn't it be possible to make changes to the php source without having to restart the whole script?

[...]

I'm planning on having a main.php file that is including user.php which contains the class MyUser

In your case, you can't. Classes can only be defined once within a running script. You would need to restart the script to have those classes redefined.

查看更多
对你真心纯属浪费
6楼-- · 2019-06-18 11:29

Runkit will allow you to add, remove, and redefine methods (among other things) at runtime. While you cannot change the defined properties of a class or its existing instances, it would allow you to change the behavior of those objects.

I don't recommend this as a permanent solution, but it might be useful during development. Eventually you'll want to store the game state to files, a database, Memcache, etc.

查看更多
干净又极端
7楼-- · 2019-06-18 11:33

You cannot include again a file with the same class, but you can do so with an array. You can also convert from array to class, if you really need to do so. This only applies to data, though, not to behavior (methods).

查看更多
登录 后发表回答