在客户端调用服务端方法时候,并不是一帆风顺的,就需要soap的异常处理来找到问题的所在:

调试我们的程序 —— 捕获异常
考虑一个我们编写代码时很可能出现的错误:在为调用的操作输入参数时,参数中某个元素的名字错误或是没有提供。例如我们把查询需要的产品代码的名字错误地写成了"ProductCod",这时运行客户端代码,是不可能得到正确的结果的。我们怎么才能发现这个错误呢?
PHP 5 中新增了很多编程语言中都提供的异常处理机制 try...catch,我们可以把客户端的实现代码包含在这个结构里 ( 需要注意的是,PHP 5 中不支持 finally 子句 ):

清单 14. 加入异常处理部分的客户端代码

try
{
$client = new SoapClient('./ProductQuery.wsdl');
$result = $client->__soapCall('QuerySpec', array( array( "ProductCod" => '1175-PXA' ) ) );
echo "Product Code:" . $client->ProductCode . "<br />";
echo "Product Code:" . $client->CPU . "<br />";
echo "Product Code:" . $client->RAM . "<br />";
echo "Product Code:" . $client->Screen . "<br />";
echo "Product Code:" . $client->HDD . "<br />";
}
catch (SoapFault $e)
{
echo $e;
}

我们会在浏览器中得到这样的输出:


清单 15. Web 服务端返回的异常信息:缺少属性

SoapFault exception:  [Client] SOAP-ERROR: Encoding: object hasn't 'ProductCode' property in  C:\xampp\htdocs\soapTest\GetProductInfo.php:17  Stack trace:  #0 C:\xampp\htdocs\soapTest\GetProductInfo.php(17): SoapClient->__soapCall('QuerySpec',  Array)  #1 {main}

在 这个例子中,异常是由 SoapClient 对象直接抛出的,它检查输入的参数,如果发现某个 WSDL 文件中定义的项没有被提供,便抛出这个异常,告诉我们"ProductCode"属性没有被提供。而我们通过有针对性的检查代码,就可以比较容易的发现错 误所在。服务端同样也可能抛出异常,这些异常通常是客户端检查时无法发现的,例如某些逻辑错误,如果我们输入了一个不合法的产品代码,就可能捕获到服务端 抛出的“不合法的产品代码”异常。为了实现这一功能,我们需要在服务端的代码中加入下面的一段语句:



清单 16. Web 服务端抛出产品代码无效的异常

if( !$result ){  throw new SoapFault("Server", "Invalid Product Code!");  }

这 段语句在未得到查询结果的情况下(这时认为原因是提供了无效的产品代码),抛出了一个 SoapFault 异常,用于创建 SoapFault 对象的参数包括错误代码,以及必要的错误信息。需要注意的是,错误代码只能使用 SOAP 标准中已定义的值,使用其他的值不会返回正确的信息。具体可使用的值可以查看 W3C 的 SOAP 文档。这样,在客户端提供无效的产品代码时,会捕获到的异常信息:


清单 17. Web 服务端返回的异常信息:产品代码无效

SoapFault exception:  [SOAP-ENV:Server] Invalid Product Code! in C:\xampp\htdocs\soapTest\GetProductInfo.php:17  Stack trace:  #0 C:\xampp\htdocs\soapTest\GetProductInfo.php(17): SoapClient->__soapCall('QuerySpec', Array)  #1 {main}

于是我们就知道提供的产品代码是无效的了。