我在处理 PHP Soap 服务器上的错误和异常时遇到困难。有时错误/异常会被我的错误/异常处理程序捕获,有时则不会。它一直让我发疯,但现在我已经能够创建一个小例子来说明这个问题。希望有人能够理解这种行为并提供一些建议。
考虑以下运行肥皂服务器的 php 文件:
<?php
set_exception_handler(function(Throwable $Exception) {
file_put_contents(__DIR__.'/exception.txt', 'Uncaught exception: '.$Exception->getMessage());
});
//throw new Exception('qwer'); // (1) Invokes the exception handler
//throw new Error('asdf'); // (2) Invokes the exception handler
function SoapFunction() {
// throw new Exception('bar'); // (3) Invokes the exception handler
// throw new Error('foo'); // (4) Does not invoke the exception handler!
}
$Server = new SoapServer(null, ['uri' => 'MyNamespace']);
$Server->addFunction('SoapFunction');
ob_start();
$Server->handle();
file_put_contents(__DIR__.'/response.txt', ob_get_flush());
有四行抛出异常,已被注释掉。
通过向肥皂服务器发送请求,将创建包含以下内容的文件
response.txt
:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="MyNamespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:SoapFunctionResponse><return xsi:nil="true"/></ns1:SoapFunctionResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
通过取消注释第一个异常
(1)
并向soap服务器发送请求,将创建包含以下内容的文件exception.txt
:
Uncaught exception: qwer
通过取消注释第二个异常
(2)
并向soap服务器发送请求,将创建包含以下内容的文件exception.txt
:
Uncaught exception: asdf
通过取消注释第三个异常
(3)
并向soap服务器发送请求,将创建包含以下内容的文件exception.txt
:
Uncaught exception: bar
通过取消注释第四个异常
(4)
并向soap服务器发送请求,文件exception.txt
将不会被创建!但文件 response.txt
将使用以下内容创建:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>foo</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
奇怪的是,第四个异常从未到达异常处理程序。相反,异常消息作为肥皂故障发送到客户端。谁能理解为什么?我正在使用 PHP 7.1.11。
对于那些想尝试的人,这里有一个简单的 php Soap 客户端。只需更改
http://www.example.com/server.php
,使其指向上述的肥皂服务器 php 文件即可。
<?php
$Client = new SoapClient(null, ['uri' => 'MyNamespace', 'location' => 'http://www.example.com/server.php']);
$Client->__soapCall('SoapFunction', []);
soap 客户端已经捕获了错误,因此它将在此时停止! 它必须重新抛出错误才能被您的处理程序捕获。
Soap Server 回顾客户端 PHP 他们的 dek-d