The current implementation of class Exception has a private "trace" member, which is used to store the backtrace. But if you throw an exception of a derived class of Exception, print_r() displays an empty "trace:private" member, as well as a "trace" (public) member that really holds the backtrace.
I deduce that the backtrace is executed/stored at the derived class level, explaining why a new public member is created. Curriously, I have also noticed that "getTrace()" returns the public one, not the private one as expected. This is not to report a bug, but to ask you not to fix it as it was intended ("trace" member as private). Indeed I use this "feature" (being able to modify the trace member) to hide an intermediate call: <? class SystemException extends Exception { function __construct($message, $code) { parent::__construct($message, $code); // Hide trace of handler() call. array_splice($this->trace, 0, 1); $this->file = $this->trace[0]['file']; $this->line = $this->trace[0]['line']; } static function handler($code, $message) { throw new SystemException($message, $code); } } set_error_handler(array('SystemException', 'handler')); ?> That way, the reported error focuses on the real file and line, not on the uninteresting intermediate handler call. In the current Exception class implementation, if both the "trace" member is private and getTrace() is final, it would be impossible to override the default behaviour. As a result, we would do our own exception base class, which goes against code reuse: need to redo all the things already done, just because the proposed class is not too open. A second consequence, is that each time you use code you've got from "outside", it could implement its own exception base class, not using the provided Exception. If so, we won't be able to write generic code that guaranties to catch all exceptions (C++ "catch(...)" or Java "finally" not implemented in PHP5, so need to specify a class for catch). The last point suggests me that PHP should guaranty that all thrown exceptions derive from Exception. It could be done in 2 ways: 1/ a fatal error when executing "throw new ...". Problem: it's not easy to simulate all error conditions, so we may deliver code that was never tested on all its "throw" branches. As a result, the script will stop on a fatal error, even though it was intented to catch and handle exceptions in a clean way. 2/ even if the class is not explicitly derived from Exception, throwing it will make it derived from Exception. Problem: an object of such a class will be an instance of Exception only after being thrown. The 2nd is my prefered one, even if I understand it could not be so easy to implement. One word about private and final: I don't think it's good programming to use them, except for security reasons. Not using them allows classes to be easily extended, in different directions, which is the goal of OOP. Moreover, all members should be protected, not public, and accessed through (virtual) methods, which guaranties that everything can be overriden if needed. Regards, Stephane -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php