Looks like Jeff’s made an unpleasant discovery while exploring Rephlux and PHP memory usage in WACT.
Adding the following to WACT’s unit test suit (which basically executes everything WACT has);
foreach (array_keys($GLOBALS) as $key) {
echo "$key=" . strlen(serialize($GLOBALS[$key]));
}
This shows up: ‘_PEAR_destructor_object_list=146270′
To support this gem, PEAR puts a reference to every object instance ever instantiated that inherits from PEAR into the global variable _PEAR_destructor_object_list. There the object stays until the deconstruction shutdown function is called. This reference prevents garbage collection of any of objects inheriting from PEAR or the memory they reference during the lifetime of the script. And it does this for no good reason at all.
The file in question is PEAR.php. And in fact I’m the guilty party for having extended from it in XML_HTMLSax (now gone with latest 3.0.0 release).
My guess is there are other projects like PhpDocumentor and anyone doing “build-like” tasks via cron, using PEAR code that could also do without donating memory to no good purpose. For PHP web applications it’s likely less of an issue but it’s still wasted overhead.
Perhaps while PEAR package developers consider where to go with PHP5 support and breaking backwards compatibility, another mission could modifying any class that extends PEAR.php directly. Better yet cut down PEAR.php itself to be a single class with a single method - isError() - which is about the only thing anyone is really using anyway.
(update) - make that two methods - isError and raiseError - typing too fast…
If you liked this blog, share the love:


May 28th, 2004 at 11:45 am
Thats why no one extends from the PEAR class unless they need destructors. In fact most people try to not even include PEAR.inc until they are actually raising an error.
May 28th, 2004 at 1:37 pm
I have found that it is very easy to code PEAR compatible classes that are a fraction the size of the PEAR ones by only implementing the methods that I use. Like you I only use isError and raiseError. The improved Error class would probably be under 1k.
The same with PEAR DB. It is posible to create a class that is under 5k that implements the methods, for a single DB type, used by 90% of PEAR DB users (connect, query, limitQuery, nextId, isError, getMessage and result: fetchRow, numRows, isError, getMessage). Compare that with 34k for DB.php, 30k for DB/mysql.php, and 62k for DB/common.php. The bloat and waste in PEAR is amazing. And lose the wasteful factory pattern.
The great things about compatable classes is that other programmers already know the interface and you can always switch back later if necessary. Maybe you WACTies can code up a set of PEAR compatable classes that are not so bloated and wasteful.
May 28th, 2004 at 6:03 pm
Hi Joshua
Yes and no. Seems like, for the most part, PEAR developers avoid it but there are a couple of exceptions which are getting widely used, like DB_Common (all the concrete DB implementations extend this) in PEAR::DB and XML_Parser (alot of the XML related packages extend XML_Parser and thereby extend PEAR). Neither of these seems to actually use the destructor functionality.
Problem then is you get into supporting your own version - more work in other words. Generally it’s not critical anyway - this is more a special case where it was.
May 28th, 2004 at 8:06 pm
i’m not sure DB_Common is a big issue - you are probably likely to only use 1 instance of it. XML_Parser is a bit more of a nightmare..
This is a bug in PEAR - the _PEAR destructor should not be defined.. - hence the array should not be created unless there is a real destructor…. Have you filed a bug :)
May 31st, 2004 at 6:14 am
“Problem then is you get into supporting your own version - more work in other words. Generally it’s not critical anyway - this is more a special case where it was.”
But Wact did its own DAOs. Why not make them PEAR DB API compatable?
“i’m not sure DB_Common is a big issue - you are probably likely to only use 1 instance of it. XML_Parser is a bit more of a nightmare..”
They both are. Too many includes; too large includes. Luckily PHP5’s PDO and XML will solve both these problems.
June 16th, 2004 at 1:27 pm
this bug is fixed now. a reference is now only stored if a PEAR destructor method is defined. So this will only affect those classes that rely on PEAR’s destructor emulation.
June 16th, 2004 at 4:41 pm
Hi Lukas,
Many thanks for the info and for fixing it.
All the best,
Harry