#33355 [Bgs->Opn]: SPL throws E_STRICT warnings as exceptions
| From: | jr at terragate dot net | Date: | Tue, 16 Aug 2005 09:45:41 +0000 |
| Subject: | #33355 [Bgs->Opn]: SPL throws E_STRICT warnings as exceptions | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-83637@lists.php.net to get a copy of this message | ||
ID: 33355
User updated by: jr at terragate dot net
Reported By: jr at terragate dot net
-Status: Bogus
+Status: Open
-Bug Type: SPL related
+Bug Type: Scripting Engine problem
Operating System: *
-PHP Version: 5CVS-2005-06-15 (dev)
+PHP Version: 5*
Assigned To: helly
New Comment:
At least it should be documented that you cannot pass an
object to a SPL class constructor that will cause execution
of PHP 4 code that will raise any E_STRICT or E_WARNING
message.
Furthermore, IMHO, this issue have still to be fixed in some
way as its takes much from SPLs potential and seems to be
inconsistent from a PHP developers point of view.
Example: Browse a WebDAV share
This could be easily done with (Recursive)DirectoryIterator
but the only available WebDAV stream Wrapper ( http://
pear.php.net/package/HTTP_WebDAV_Client ) is written in PHP
4.
So you could simply write a new PHP 5 Wrapper but most of
XML/HTTP/Network stuff have to be done from scratch as
almost all available classes for it are still PHP 4.
After looking into PHP internals I figured out that the is_a
deprecation warning seems to be the only E_STRICT message in
the code that isn't issued at compile time.
Thus handling is_a at compile time (as its done with
instanceof) would be another way to fix the issue but
requires some changes to the lexer and parser.
I am willing to do this if there is a chance that such a
modification have a chance of being applied.
Previous Comments:
------------------------------------------------------------------------
[2005-06-16 19:38:30] helly@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
In this case i don't see any motivation to change since you shouldn't
be using is_a() anyway.
However the point is that unfortunatley some php internal api's do not
support detailed error informations. In fact no php internal code can
deliver detailed exceptions with the exception being a few xml and spl
classes. Thus it is not a problem of SPL which here only makes use of
other api's.
The reason SPL now needs to throw on warnings is that some of the
warnings mean that the object cannot be initialized thus being in an
invalid state so that it needs to be assuered that the constructor
fails so that the object cannot be used.
Since i cannot distunguish the cause of the error i am forced to throw
on any error. Actually i could limit it to E_WARNING but then again i'd
need to change a lot of php internal things.
------------------------------------------------------------------------
[2005-06-15 17:14:00] jr at terragate dot net
Description:
------------
Currently SPL sets the error_handling to EH_THROW which will
cause any E_WARNING or E_STRICT message to be thrown as
exception regardless of error_reporting's settings.
This renders most code with compatibility in mind (e.g.
PEAR) useless in SPL context since there is no way to ignore
non fatal warnings.
At least E_STRICT messages shouldn't be thrown if it is
disabled in error_reporting.
But this might still be confusing. E_STRICT massages should
be treated as compile time warnings (as in most other
languages). They shouln't affect the control flow if not
explicitly requested.
Generally the same applies to E_WARNING and E_USER_WARNING
as long as there is no way to disable EH_THROW in user space
php code.
IMHO EH_THROW should be completly disabled or the error mode
should be made controlable:
// ignore warnings from this wrapper
error_mode(EH_NORMAL);
$it = new DirectoryIterator('legacywrapper://path/');
// I want to stop on some warnings
error_mode(EH_THROW);
try {
$it = new DirectoryIterator('legacywrapper://path/');
} catch(Exception $e) {
// parse exception which might contain an E_WARNING
message
// this is not really OO but it works
...
if($criticalWarning) {
// bail out
throw new AMoreAppropriateException();
} else {
// non critical warning trying again with EH_NORMAL
// using normal php error/warning handling here
...
}
}
As long as all warnings are thrown as 'Exception' the
EH_THROW mode can't be used as different warnings cannot be
easily distinguished.
Reproduce code:
---------------
<?php
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
class StreamWrapper
{
public function dir_opendir($path, $options) {
return !is_a(null, 'AKnownOrUnknownClass');
}
public function dir_readdir() {
return array();
}
}
stream_wrapper_register('test', 'StreamWrapper');
echo "Done\n";
?>
Expected result:
----------------
Output of "Done"
Actual result:
--------------
Fatal error: Uncaught exception 'Exception' with message 'is_a
(): Deprecated. Please use the instanceof operator' in /Users/
reith2/Projects/php/bug-new.php:8
Stack trace:
#0 /Users/reith2/Projects/php/bug-new.php(8): is_a(NULL,
'AKnownOrUnknown...')
#1 /Users/reith2/Projects/php/bug-new.php(18): StreamWrapper-
>dir_opendir('test://path/', 4)
#2 /Users/reith2/Projects/php/bug-new.php(18):
DirectoryIterator->__construct('test://path/')
#3 {main}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=33355&edit=1