For example, you gave the example of using file() to read a non-existant file. Well, perhaps you might check to see if the file exists (and is readable) first by calling is_readable. This will allow you to send a more intelligent Fault to your clients.
In Java, we'd get around this problem by wrapping the file read operation in a try/catch block. You can't do that directly in PHP 4 ( but PHP 5 will provide this), so you have to sort of simulate this by using other functions to validate your arguments before hand.
Also, I do believe that an E_NOTICE error should cause a SOAP Fault. Something went wrong when your script tried to process the data given to it. Rather than trying to tell PHP to ignore it, I would suggest that you instead focus on catching the error in the first place.
== Will Green
Jon Day wrote:
Hello There:
I would like to start out by saying that I am glad that this community
exists - and I am very grateful for everyone's contributions. I have just
spent the last day in heavy SOAP development with PEAR and discovered a
bug/wrinkle that causes major problems when dealing with error handling.
In short, the Server.php file's SOAP_ServerErrorHandler function does not
check the error_reporting level before it sets $soap_server_fault. This has
become very annoying because a simple E_NOTICE error causes the server to
return a soap fault!
My first thought was to use php's error_reporting() feature to ignore
E_NOTICE errors, only to realize that the library ignores this setting
completely when handling an error (for two reasons: 1. There is no code in
the function SOAP_ServerErrorHandler to check the error_reporting level; 2.
Even if such code existed, you would have to set error_reporting(E_<blah>)
in all your server methods, since your server methods are called by
SOAP_Server with the @ symbol, which sets error_reporting to nothing for the
scope of the method).
The PHP manual suggests the following when using custom error handlers:
"error_reporting() settings will have no effect and your error handler will
be called regardless - however you are still able to read the current value
of error_reporting and act appropriately. Of particular note is that this
value will be 0 if the statement that caused the error was prepended by the
@ error-control operator."
That means that as of right now, if you have a line of code executed that
looks like this:
$file = @file('/path/to/a/non/existant/file');
.. then your soap server will return a soap fault, regarless of what
error_reporting is set to! Even when the above errorsome "file" funciton
call is prefixed with the @ symbol! How do we solve these issues?
There are two changes that need to be made to the Server.php file. First,
removing the @ error-control operator on all the server method calling code
(they are not needed because a custom error handler was set using
set_error_handler, which catches errors anyway... so all these symbols
actually do is change the error_reporting level in the scope of the called
server method. Second is to update the SOAP_ServerErrorHandler callback
function to check the level of error_reporting and decide whether or not an
error should be logged to the global $soap_server_fault (which is later
check for and returned as a soap fault to the client if set).
In case you didn't realize yet, I'm referring to the Server.php which has
moved to the ZEND_ENGINE_1 branch of cvs. (v1.44.2.1 2003/12/20 from CVS). I
have a clean patched version of the file for the cvs maintainer(s) (Shane?).
Please let me know who I should send the patched file to -
Any comments welcome!
Thanks for listening,
Jon
PS Below is the result of cvs diff after my modifications for the Server.php file in question:
=================================================================== RCS file: /repository/pear/SOAP/Server.php,v retrieving revision 1.44.2.1 diff -r1.44.2.1 Server.php 32,34c32,38 < $detail = "Errno: $errno\nFilename: $filename\nLineno: $linenum\n"; < // XXX very strange behaviour with error handling if we =& here. < $soap_server_fault = new SOAP_Fault($errmsg, 'Server', 'PHP', $detail); ---
// only set the $soap_server_fault global if the the error_reporting
level says so
// added by Jon Day <php.soap@jonathanday.com> if ((error_reporting() & $errno) == $errno) { $detail = "Errno: $errno\nFilename: $filename\nLineno:
$linenum\n";
// XXX very strange behaviour with error handling if we =& here. $soap_server_fault = new SOAP_Fault($errmsg, 'Server', 'PHP',
$detail);
}
239c243 < $ret = @call_user_func_array(array(&$this->soapobject, $methodname),$args); ---
$ret = call_user_func_array(array(&$this->soapobject,
$methodname),$args); 241c245 < $ret = @call_user_func_array($methodname,$args); ---
$ret = call_user_func_array($methodname,$args);
246c250 < $ret = @call_user_func(array(&$this->soapobject, $methodname)); ---
$ret = call_user_func(array(&$this->soapobject,
$methodname)); 248c252 < $ret = @call_user_func($methodname); ---
$ret = call_user_func($methodname);
-- William Green President, HotGazpacho Consulting, Inc. 11801 50th St. N #A11 Tampa, FL 33617
813-988-4338 (Office) 813-892-2414 (Mobile)
-- PHP Soap Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php