# Class Destruction / Reloading

- Thread: https://externals.io/message/12228
- Original archive: https://news-web.php.net/php.internals/12228
- Started by Sean Coates on 2004-08-18T22:01:25+00:00
- Messages: 17
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #12228 — Sean Coates — 2004-08-18T22:01:25+00:00

URL: https://externals.io/message/12228#12228

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello Internals,

Has anyone given thought to a feature that allows (PHP) developer to
invalidate classes (allowing the developer to re-load the class, with
modified code)? I realize that this is not possible now, and for good
reason. But I think the idea has potential.

I asked Sara about this, yesterday, after the idea occurred to me, and
she graciously whipped up a small extension that does exactly what I'm
looking for, but she told me she thought it was a bad idea to be doing
this (and also allows destruction of functions). I agree: without the
proper safety nets, this is a dangerous thing to be doing.

So, why do I want this functionality, in the first place? Consider a
long-running application (not a web page, but, for instance, a
sockets-based application). It would be very useful for me, as a
developer, to be able to re-load parts of the application, without
tossing the whole current instance of PHP (and all associated resources)
- -- ie, doesn't release socket connections, but allows re-loading of the
associated handlers. This could be accomplished by invalidating a class
(destroying it, and marking all instanciated objects with a special type
(__PHP_Destroyed_Class comes to mind, after __PHP_Incomplete_Class), and
re-declaring the class.

- -- sample code (working) --
<?php
eval('Class Foo { function name() {  echo "Foo\n";  } }');
Foo::name();
shiva_destroy_class('Foo');
eval('Class Foo { function name() {  echo "Bar\n";  } }');
Foo::name();
?>
- -- output --
Foo
Bar

I also spoke (typed) with Stig, who told me that this sounds more like a
PHP 6 feature. I understand that class destruction breaks a lot of
assumptions. As Sara pointed out, it will definitely break optimizers.
Also, the potential for segfault is very high:
Class Foo { function name() {  echo "Foo\n";  } }; $Foo = new Foo();
shiva_destroy_class('Foo'); eval('Class Foo { function name() {  echo
"Bar\n";  } };'); $Foo->name();   results in segfault..

I'm, admittedly, completely out of my league here.. I played with the
API a little, and was reminded of this. (-:

It may seem like a stupid idea at first, but I think there's some value
in re-loading pieces of code, and with the proper object
counting/invalidation, sounds like it could be safe, but like I said, I
don't know what I'm doing.

Is this worth further discussion?

S
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFBI9G1WppknrQMxQIRAjPOAJ9gsQ6AZlwd5QI6+CYerGOgtsKwhQCfejxZ
zfMP6MgKuGvHx7dO4mPNh90=
=GR/W
-----END PGP SIGNATURE

---

## #12231 — Greg Beaver — 2004-08-18T23:01:23+00:00

URL: https://externals.io/message/12228#12231 · In reply to: #12228

Sean Coates wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hello Internals,
> 
> Has anyone given thought to a feature that allows (PHP) developer to
> invalidate classes (allowing the developer to re-load the class, with
> modified code)? I realize that this is not possible now, and for good
> reason. But I think the idea has potential.
[snip]
> Is this worth further discussion?

There is a clever php4 implementation that allows loading/unloading of 
methods, info at http://pear.php.net/pepr/pepr-proposal-show.php?id=68 
It does not use any engine magic and might be of use to you while you 
wait for PHP 6. :)

Greg

---

## #12232 — Marcus Boerger — 2004-08-18T23:09:35+00:00

URL: https://externals.io/message/12228#12232 · In reply to: #12228

Hello Sean,

Thursday, August 19, 2004, 12:01:25 AM, you wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1

> Hello Internals,

> Has anyone given thought to a feature that allows (PHP) developer to
> invalidate classes (allowing the developer to re-load the class, with
> modified code)? I realize that this is not possible now, and for good
> reason. But I think the idea has potential.

[................]

> Is this worth further discussion?

Not before until we have an application server and php scripts that are
designed to run for several months. And even then we would also need
improved Reflection support and conatiner support and so on and so on.

Best regards,
 Marcus                            mailto:helly@php.net

---

## #12235 — Sean Coates — 2004-08-19T00:23:56+00:00

URL: https://externals.io/message/12228#12235 · In reply to: #12232

Marcus Boerger wrote:
> > […]
 >
 > Not before until we have an application server and php scripts that are
 > designed to run for several months. And even then we would also need
 > improved Reflection support and conatiner support and so on and so on.

No disrespect intended, but this sounds like a chicken-and-egg problem
to me.

S
(PS- Wez, I remembered to turn off my signing this time (-:  )

---

## #12245 — Antony Dovgal — 2004-08-19T05:04:36+00:00

URL: https://externals.io/message/12228#12245 · In reply to: #12228

On Wed, 18 Aug 2004 18:01:25 -0400
Sean Coates <sean@caedmon.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Hello Internals,
> 
> Has anyone given thought to a feature that allows (PHP) developer to
> invalidate classes (allowing the developer to re-load the class, with
> modified code)? I realize that this is not possible now, and for good
> reason. But I think the idea has potential.
> 
<skip>
> - -- sample code (working) --
> <?php
> eval('Class Foo { function name() {  echo "Foo\n";  } }');
> Foo::name();
> shiva_destroy_class('Foo');
> eval('Class Foo { function name() {  echo "Bar\n";  } }');
> Foo::name();
> ?>
> - -- output --
> Foo
> Bar


Well, some time ago I wrote a small functions, that does exactly the same:

PHP_FUNCTION(unregister_class)
{
zval **class;
zend_class_entry *ce = NULL, **pce;
char *lowercase_name = NULL;

if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &class)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}

convert_to_string_ex(class);

if (zend_lookup_class(Z_STRVAL_PP(class), Z_STRLEN_PP(class), &pce TSRMLS_CC) == SUCCESS) {
ce = *pce;
}

if (!ce) {
RETURN_FALSE;
}

lowercase_name = emalloc(ce->name_length+1);
zend_str_tolower_copy(lowercase_name, ce->name, ce->name_length);

if (zend_hash_del(CG(class_table), lowercase_name, ce->name_length+1) == FAILURE) {
efree(lowercase_name);
RETURN_FALSE;
}

efree(lowercase_name);
RETURN_TRUE;
}

Dunno if it's a good implementation, but the idea was to be able to reload classes in the looong running PHP application.
However, I don't think it should be implemented in PHP ever, 'cos this (and many more) functionality is/should be implemented in SRM.

-- 
Wbr,
Antony Dovgal aka tony2001
tony2001@phpclub.net || antony@dovgal.com

---

## #12248 — Sara Golemon — 2004-08-19T05:32:20+00:00

URL: https://externals.io/message/12228#12248 · In reply to: #12245

> Well, some time ago I wrote a small functions, that does exactly the same:
>
> PHP_FUNCTION(unregister_class)
> {
*snip*

Barring some stylectic differences and a check to make sure it's not an
internal class, that's precisely what I gave sean in
shiva_destroy_class()....

But just to be clear, I don't think it's a good idea, and I'll wager dollars
to doughnuts that it destablizes the active request if not the entire
engine.

Not to be too blunt, but I gave him that extension so he'd have some rope to
hang himself with (or maybe learn something useful...)

-Sara

---

## #12257 — Zeev Suraski — 2004-08-19T07:53:46+00:00

URL: https://externals.io/message/12228#12257 · In reply to: #12245

At 08:32 19/08/2004, Sara Golemon wrote:
> > […]
>*snip*
>
>Barring some stylectic differences and a check to make sure it's not an
>internal class, that's precisely what I gave sean in
>shiva_destroy_class()....
>
>But just to be clear, I don't think it's a good idea, and I'll wager dollars
>to doughnuts that it destablizes the active request if not the entire
>engine.

 From the technical perspective, it's actually easy to implement in a 
rock-solid manner.  Don't kill the class completely but just clean any 
functions/properties inside of it, and mark it as dead.  Then patch the 
class declaration begin code to check for this flag, and reuse the class 
structure instead of complaining about reregistering a class.  There might 
be some more cleanup necessary in PHP 5, but if any, it shouldn't be too 
complicated.

But I agree with you that it's a bad idea :)

Zeev

---

## #12260 — Robert Janeczek — 2004-08-19T08:29:31+00:00

URL: https://externals.io/message/12228#12260 · In reply to: #12232

> > […]
>
> Not before until we have an application server and php scripts that
> are designed to run for several months. And even then we would also
> need improved Reflection support and conatiner support and so on and
> so on.

don`t you think that lacking this destruction/loading causes potential app
server developers to drop their idea? i`m working on such thing and working
on components in write code-[ctrl-c server]-load server isn`t fun at all :]

rash

---

## #12267 — Marcus Boerger — 2004-08-19T18:10:12+00:00

URL: https://externals.io/message/12228#12267 · In reply to: #12260

Hello Robert,

Thursday, August 19, 2004, 10:29:31 AM, you wrote:

> > […]

> don`t you think that lacking this destruction/loading causes potential app
> server developers to drop their idea? i`m working on such thing and working
> on components in write code-[ctrl-c server]-load server isn`t fun at all :]

Could you share some more infos about that project?

marcus

---

## #12268 — Robert Janeczek — 2004-08-19T19:17:44+00:00

URL: https://externals.io/message/12228#12268 · In reply to: #12267

> Could you share some more infos about that project?

sure

the project itself is my university thesis, its topic might clear some
things: 'Hive -distributed server for message-driven componental PHP
applications'. main idea is to be able to create php applications in
RAD-way. for this to be possible i designed componental architecture based
on messaging system. it is exacly the way php is NOT designed to be used ;)

all this with transparent component distribution in mind. server runs as
standalone appliacation. http daemon uses sockets to transfer request
parameters and fetch results - later i`ll probably build into app server
simple httpd. server is ('will be' mostly) coded in php, so changes can be
made easily, but if my idea will be useful i have in mind rewriting code in
c. no stress tests have been made so far - to much coding is still to be
done.

it is mix of ideas from java, windows messaging and few very theoretical
books. behind my back lies 1 meter high mountain of books :)

from practical point of view - its something like srm, at least i think so -
i`ve never used it. from the beginning its designed for php5 new super duper
mechanisms.

by now you probably realized why i`ve showed up in this thread - ability to
manage components flexible is crucial in my project. i need for example way
to detect class name collisions before compiler dies with error - there is
no way to control naming conventions for components. i thought about some
nasty ideas like forcing names in HIVE_UUID form, but as you surely
understand - its horrible solution. probably i`ll have to use second process
to load component and use reflection to check for collisions before loading
in main app server process.

rash
ps. no thread support sucks :]

---

## #12282 — Sara Golemon — 2004-08-20T20:27:20+00:00

URL: https://externals.io/message/12228#12282 · In reply to: #12257

>  From the technical perspective, it's actually easy to implement in a
> rock-solid manner.  Don't kill the class completely but just clean any
> functions/properties inside of it, and mark it as dead.  Then patch the
> class declaration begin code to check for this flag, and reuse the class
> structure instead of complaining about reregistering a class.  There might
> be some more cleanup necessary in PHP 5, but if any, it shouldn't be too
> complicated.
>
  I took this in a slightly different direction:
http://pecl.php.net/classkit  Any and all thoughts appreciated.

Function Entries:
    bool classkit_method_add(string classname, string methodname, string
args, string code[, long flags])
    bool classkit_method_redefine(string classname, string methodname,
string args, string code[, long flags])
            Note: flags parameter requires PHP >= 5.0.0
    bool classkit_method_remove(string classname, string methodname)
    bool classkit_method_rename(string classname, string methodname, string
newname)

Constants (passed in flags parameter):
    CLASSKIT_ACC_PUBLIC
    CLASSKIT_ACC_PROTECTED
    CLASSKIT_ACC_PRIVATE

-Sara

---

## #12611 — Alex Pagnoni — 2004-09-06T12:27:28+00:00

URL: https://externals.io/message/12228#12611 · In reply to: #12282

Sara Golemon wrote:

>   I took this in a slightly different direction:
> http://pecl.php.net/classkit  Any and all thoughts appreciated.

Sara, seems very interesting to me. Anyway, can you please provide me 
your shiva_destroy_class() extension?

I need something similar in order to reload classes for an open source 
EJB like system I built, when redeploying code with already declared 
classes.

Rasmus was right when he said "PHP is getting stronger in order to 
provide more powerful tools to solve the same set of problems people 
have been using PHP for all along", when talking about the "PHP becoming 
Java".

I love PHP and I use it wherever possible, coding in PHP is fun for me; 
and more features may means more new possibilities, such as that project 
I built. I know that it is using PHP in a way it wasn't originally meant 
for; but it works, and PHP made it possible, and if it allowed me to do 
it, then it is "legal" to do such sort of things ;)

PS. For the interested ones, this is a list of current features:

- Encapsulates business logic in a Carthag Business Module (CBM)
- Delivers optional persistance, with Value Objects and Data Access Objects
- CBM deployer
- Transparent access to remote CBMs as if they were local
- Transparent access to local CBMs without using CBM server
- Location of CBMs through a CBM locator descriptor
- Own socket server for receiving requests and serving classes
- Uses XML-RPC as communication protocol
- Uses PHP internal XML-RPC server implementation for faster speed
- Watchdog for monitoring CBM server and restarting it in case of failure
- Supports CBM session for the entire lifetime of a remote object

Alex

---

## #12612 — Alex Pagnoni — 2004-09-06T12:28:35+00:00

URL: https://externals.io/message/12228#12612 · In reply to: #12282

Sara Golemon wrote:

>   I took this in a slightly different direction:
> http://pecl.php.net/classkit  Any and all thoughts appreciated.

Sara, seems very interesting to me. Anyway, can you please provide me 
your shiva_destroy_class() extension?

I need something similar in order to reload classes for an open source 
EJB like system I built, when redeploying code with already declared 
classes.

Rasmus was right when he said "PHP is getting stronger in order to 
provide more powerful tools to solve the same set of problems people 
have been using PHP for all along", when talking about the "PHP becoming 
Java".

I love PHP and I use it wherever possible, coding in PHP is fun for me; 
and more features may means more new possibilities, such as that project 
I built. I know that it is using PHP in a way it wasn't originally meant 
for; but it works, and PHP made it possible, and if it allowed me to do 
it, then it is "legal" to do such sort of things ;)

PS. For the interested ones, this is a list of current features:

- Encapsulates business logic in a Carthag Business Module (CBM)
- Delivers optional persistance, with Value Objects and Data Access Objects
- CBM deployer
- Transparent access to remote CBMs as if they were local
- Transparent access to local CBMs without using CBM server
- Location of CBMs through a CBM locator descriptor
- Own socket server for receiving requests and serving classes
- Uses XML-RPC as communication protocol
- Uses PHP internal XML-RPC server implementation for faster speed
- Watchdog for monitoring CBM server and restarting it in case of failure
- Supports CBM session for the entire lifetime of a remote object

Alex

---

## #12613 — Alex Pagnoni — 2004-09-06T12:30:52+00:00

URL: https://externals.io/message/12228#12613 · In reply to: #12282

Sara Golemon wrote:

 >   I took this in a slightly different direction:
 > http://pecl.php.net/classkit  Any and all thoughts appreciated.


Sara, seems very interesting to me. Anyway, can you please provide me 
your shiva_destroy_class() extension?

I need something similar in order to reload classes for an open source 
EJB like system I built, when redeploying code with already declared 
classes.

Rasmus was right when he said "PHP is getting stronger in order to 
provide more powerful tools to solve the same set of problems people 
have been using PHP for all along", when talking about the "PHP becoming 
Java".

I love PHP and I use it wherever possible, coding in PHP is fun for me; 
and more features may means more new possibilities, such as that project 
I built. I know that it is using PHP in a way it wasn't originally meant 
for; but it works, and PHP made it possible, and if it allowed me to do 
it, then it is "legal" to do such sort of things ;)

PS. For the interested ones, this is a list of current features:

- Encapsulates business logic in a Carthag Business Module (CBM)
- Delivers optional persistance, with Value Objects and Data Access Objects
- CBM deployer
- Transparent access to remote CBMs as if they were local
- Transparent access to local CBMs without using CBM server
- Location of CBMs through a CBM locator descriptor
- Own socket server for receiving requests and serving classes
- Uses XML-RPC as communication protocol
- Uses PHP internal XML-RPC server implementation for faster speed
- Watchdog for monitoring CBM server and restarting it in case of failure
- Supports CBM session for the entire lifetime of a remote object

Alex

---

## #12614 — Alex Pagnoni — 2004-09-06T13:47:51+00:00

URL: https://externals.io/message/12228#12614 · In reply to: #12611

Please excuse me for repeated messages, I got some timeouts when posting 
from the news server gateway.

---

## #12617 — Sara Golemon — 2004-09-06T14:58:07+00:00

URL: https://externals.io/message/12228#12617 · In reply to: #12611

> > […]
>
> Sara, seems very interesting to me. Anyway, can you please provide me
> your shiva_destroy_class() extension?
>
Shiva's not anything approaching stable or trustable.  It's just a five
minute exercise I wrote for Sean Coates to illustrate some of the inherent
dangers of futzing around with the class table.

If you need class redefinition, I would much sooner recommend
classkit_import() which will aggregate all the methods from a new class
definition over the top of an old class entry. (Note: It's been documented
in CVS, it just hasn't shown in the manual build yet:
http://cvs.php.net/co.php/phpdoc/en/reference/classkit/functions/classkit-import.xml )

I'll also note that while this extensions is more trustable than Shiva, it's
*also* marked as beta.  Sean (who uses this far more than I actually do)
mentioned a bug (non-crashing, but it raises `E_ERROR` and halts your current
script) when classkit_import() is used under certain conditions (something
involving importing multiple classes in a single file, we're working through
the specifics still).

If you don't so-much want to redefine the class as undefine it, I suppose it
could be done safely by following the idea in Zeev's earlier post which
involves "hiding" the class rather than outright destroying it.  That way if
there are any instances hiding in some obscure symbol table somewhere (e.g.
another instantiated object, a static variable hash or a local variable hash
in an upstream function/method) they'll still have a class_entry to refer
to.  This is something I could add to classkit, but because the class
definitions don't really disappear but are rather just "hidden", it'll
appear to "leak" a little bit of memory each time it's used so again, I'd
recommend classkit_import() over it.

Before you ask: No, it's not "simple enough" to just go looking through
those symbol tables to see if any instances exists.  Possible yes, practical
no.

-Sara

---

## #12627 — Alex Pagnoni — 2004-09-07T08:43:35+00:00

URL: https://externals.io/message/12228#12627 · In reply to: #12617

Sara Golemon wrote:

 > If you need class redefinition, I would much sooner recommend
 > classkit_import() which will aggregate all the methods from a new class
 > definition over the top of an old class entry. (Note: It's been 
documented

Sara, thank you very much for your suggestion. This should be enough for 
my needs, I'm going to study/test it. Redefining only is ok for me, 
anyway having the option of removing (hiding) a class may be interesting 
too.

Alex
