unload/reload classes?

php.internals

Rasmus Schultz

7 years ago
Hello internals, How hard would be to add an unload (or reload) feature for classes/interfaces? I'm wondering with regards to running PHP as a deamon (with Swoole or ReactPHP, etc.) could it be made possible to hot-reload e.g. for controllers and view-models? Of course, the other option is to launch worker sub-processes under some sort of host process, and then restart the workers after a change - this adds communication overhead between the host/worker processes though, and a layer of complexity. Another option is if a reverse proxy (NGINX maybe) could restart the actual application daemon, but that means you have a dependency on a specific reverse proxy. So I know there are other options, but I'm looking for the simplest and cleanest way to do this, and I'd prefer to stay within the language. Other dynamic languages (where daemonizing is "normal", like Ruby, JS and Python) have this feature and it is often used to hot-reload controllers/views in web-apps. Any thoughts?

Robert Hickman

7 years ago
(I'm not a internals developer, but here are some ideas:) 1: I have seen an extension which allows functions/classes to be redefined, although I can't remember what it is called. 2: It is possible to dynamically reload code if defined as anonymous classes or functions using return include: <file_1.php> <?php return class { function some_function($a, $b) { return $a + $b; } }; <file_2.php> $class = include "file_1.php"; $class->some_function(1,2); ---------------- This would entail creating a custom namespace system, and a facility to watch and re-include files. I don't know if the old bytecode of 'orphaned' objects would be garbage collected. 3: Another option would be to create a watcher on the files and just kill and reload the php process on file changes. This would be easier if the application state is all stored externally. 4: Use Ruby/JS/Python instead? On Mon, 18 Mar 2019 at 20:16, Rasmus Schultz <rasmus@mindplay.dk> wrote:

Ben Ramsey

7 years ago
> On Mar 18, 2019, at 18:45, Robert Hickman <robehickman@gmail.com> wrote: > > 1: I have seen an extension which allows functions/classes to be > redefined, although I can't remember what it is called.
Maybe you’re thinking of the runkit extension? https://secure.php.net/manual/en/book.runkit.php Cheers, Ben

Robert Hickman

7 years ago
On Tue, 19 Mar 2019 at 00:55, Ben Ramsey <ben@benramsey.com> wrote:
> > > On Mar 18, 2019, at 18:45, Robert Hickman <robehickman@gmail.com> wrote: > > > 1: I have seen an extension which allows functions/classes to be > redefined, although I can't remember what it is called. > > > > Maybe you’re thinking of the runkit extension? https://secure.php.net/manual/en/book.runkit.php > > Cheers, > Ben
Yes that's what I was thinking of. Looking at it there is 'runkit_function_redefine' but no 'runkit_class_redefine', only facility to redefine individual methods of an existing class. Thus not matching Rasmus Schultz request. The sandboxing facility of runkit may make dynamic reload possible, if a new sandbox were created when reload was desired. That's just me reading the API docs though, I haven't tried it.

Christoph Becker

7 years ago
On 19.03.2019 at 11:30, Robert Hickman wrote:
> On Tue, 19 Mar 2019 at 00:55, Ben Ramsey <ben@benramsey.com> wrote: > >> On Mar 18, 2019, at 18:45, Robert Hickman <robehickman@gmail.com> wrote: >> >> 1: I have seen an extension which allows functions/classes to be >> redefined, although I can't remember what it is called. >> >> Maybe you’re thinking of the runkit extension? https://secure.php..net/manual/en/book.runkit.php > > Yes that's what I was thinking of. Looking at it there is > 'runkit_function_redefine' but no > 'runkit_class_redefine', only facility to redefine individual methods > of an existing class. Thus > not matching Rasmus Schultz request. The sandboxing facility of runkit > may make dynamic > reload possible, if a new sandbox were created when reload was > desired. That's just me > reading the API docs though, I haven't tried it.
There is runkit_import(), which will overwrite existing class definitions. However, runkit is still not compatible with PHP 7 to my knowledge. Don't know whether runkit7[1] supports it. [1] <https://github.com/TysonAndre/runkit7>
-- Christoph M. Becker