The following patch:
http://marcus-boerger.de/php/ext/exception.diff
allows in a short, straight forward and easy way to suppress errors and
optionally throw exceptions instead. This is supposed to be automated
by the try opcode (but that is another discussion).
The problem:
During development of SQLite i found the problem that i had to inform
the user about an error inside a constructor. This can only be done by
throwing an exception. (Repeat: this cannot be done otherwise). The
main problem herin is that we have many little utility functions that may
raise errors (like safe mode and such).
This means we had to rewrite the whole api, pass information around
or find a generic solution.
Ok here goes:
First i fixed the "ignore repeated errors" feature. Then i added some control
information to struct _php_core_globals:
error_handling_t error_handling;
zend_class_entry *exception_class;
error_handling can be one of EH_NORMAL, EH_SUPPRESS and EH_THROW
- EH_NORMAL is the normal way errors are handled
- EH_SUPPRESS means the error is stored but not shown (suppressed even)
- EH_THROW throws an exception of type PG(exception_class) or the default
exception class if PG(exception_class) is NULL.
To manually change the mode or class there is the following function:
PHPAPI void php_set_error_handling(error_handling_t
error_handling, zend_class_entry *exception_class TSRMLS_DC)
The mechanism itself is located in the function php_error_cb which is called
during all error calls. So every error, warning or notice is catched. BUT of
corse the mechanism doesn't work with E_ERROR, E_PARSE
or such. These
are real errors and are errors even after the patch.
The reason the exception class can be set is to easily support exception
inheritance
for the lazy programmers.
The reason to support EH_SUPPRESS is for more sophisticated problems...
When the mechanismn throws an error it automatically sets these exception
properties:
- message the error message
- file the filename
- line the line number in the file
Further more i suggest we add the severity to the default exception.
Some help of the engine would be good:
- automatically set EH_THROW mode at "try"
- automatically set EH_NORMAL mode at "catch" (first outmost catch)
If noone objects i will commit this on monday evening.
Unfortunately there is a memory leak in the exception handling itself but
that is another story...and will hopefully soon be fixed by somebody else.
Anybody interested can try the patch with my patched SQLite:
http://marcus-boerger.de/html/php/ext/sqlite/
and especially look into test sqlite_oo_020.phpt
regards
marcus
--
------------------->>> mailto:mail@marcus-boerger.de <<<------------------
"We are animals among animals, all children of matter,
save that we are the more disarmed. But since, unlike animals,
we know that we must die, let us prepare for that moment
by enjoying the life that has been given us by chance and for chance."
Umberto Eco, The island of the day before
--------------------->>> http://marcus-boerger.de <<<
At 02:53 04.05.2003, Marcus Börger wrote:
[...]
Anybody interested can try the patch with my patched SQLite:
Ha, to late here already
http://marcus-boerger.de/php/ext/sqlite/
At 02:53 AM 5/4/2003 +0200, Marcus Börger wrote:
Some help of the engine would be good:
- automatically set EH_THROW mode at "try"
- automatically set EH_NORMAL mode at "catch" (first outmost catch)
Huh? I think it's definitely not obvious that I'd want these to happen
automatically. Actually I personally wouldn't, because I'd prefer PHP to
continue the way it works and only use exceptions in user-land.
If noone objects i will commit this on monday evening.
Please don't before this is discussed. We have discussed this kind of thing
quite a few times and our opinion was that error handling in PHP shouldn't
be changed. We wouldn't want some configuration switch to change how the
scripts work nor is it a good idea if the same script behaves differently
according to one switch.
Anyway, we can discuss this again but definitely I don't think we should
jump the gun with commits in this area until people really think of the
whole picture. We have a large user base out there and we still want all of
the user-base to "talk" in the same language.
I won't really be around for the next two weeks so maybe it's best to wait
or in the least make sure Zeev takes part in this discussion.
Thanks,
Andi
P.S. -BTW, what does SQLite do?
At 04:32 04.05.2003, Andi Gutmans wrote:
At 02:53 AM 5/4/2003 +0200, Marcus Börger wrote:
Some help of the engine would be good:
- automatically set EH_THROW mode at "try"
- automatically set EH_NORMAL mode at "catch" (first outmost catch)
Huh? I think it's definitely not obvious that I'd want these to happen
automatically. Actually I personally wouldn't, because I'd prefer PHP to
continue the way it works and only use exceptions in user-land.If noone objects i will commit this on monday evening.
Please don't before this is discussed. We have discussed this kind of
thing quite a few times and our opinion was that error handling in PHP
shouldn't be changed. We wouldn't want some configuration switch to change
how the scripts work nor is it a good idea if the same script behaves
differently according to one switch.
There will surely no switch, that would be the stuiest thing we cold do.
Anyway, we can discuss this again but definitely I don't think we should
jump the gun with commits in this area until people really think of the
whole picture. We have a large user base out there and we still want all
of the user-base to "talk" in the same language.
Large user base? Who the hell uses ze2 or php5 widely out there?
The patch is intended for the new php5/ze2 oo features and will not change
any php4 features or its behavior.
It simply makes it possible to throw exceptions in ctors (and for that
there is now other solution).
Everything else the patch offers can surely be discussed: automation with
try/catch and so on.
What i like would be:
- procedural (aka php4) no change (aka simply errors as of now)
- oo (aka new php5/ze2 features) always throw exceptions instead of errors.
for example:
let's assume we have an extension "example" consisting of a function
"example_test", a namespace "example"
containing a function "factory" and a class "whatever" with a "whatelse":
example_test(); //-> normal operation or error mechanism
$obj = example::factory(); // -> object creation or exception
$obj = new example::whatever(); // -> object creation or exception
$obj->whatelse(); // -> normal operation or exception
WHY: becasue this only changes new things we don't have yet and it is easy
to learn
and deal with: "procedural = errors, oo = exceptions".
I won't really be around for the next two weeks so maybe it's best to wait
or in the least make sure Zeev takes part in this discussion.
Then i hope you can answer now :-)
Thanks,
AndiP.S. -BTW, what does SQLite do?
Just as Wez said. And you may take a look at my patches and tests for it on
the url i gave. Because this
extension lets you test exceptions with ctors and the factory() function.
regards
marcus
At 20:17 04.05.2003, l0t3k wrote:
along the lines of this discussion, i had posted a (ignored) message
concerning the behaviour of zend_parse_parameters. my point was/is that
there should be an extra parameter which determines whether a regular PHP
error or exception is raised. otherwise its useless to use in an OO
extension (particularly in the case of constructors). if we adopt this
approach, i think we'd also need an IllegalArgumentException or somesuch.
My patch opens the doors to such behavior :-)
regards
marcus