我变得绝望,我想要的只是简单的错误处理,当PHP SOAP Web服务停止以回显错误消息登录服务时。请帮帮我!
目前它仍然显示错误(以及警告......):
Fatal error: SOAP-ERROR: Parsing WSDL
这是脚本:
<?php
session_start();
$login="0000000000000nhfidsj"; //It is like this for testing, It will be changed to a GET
$username = substr($login,0,13); //as password is always 13 char long
//(the validation is done int he javascript)
$password = substr($login,13);
try
{
ini_set('default_socket_timeout', 5); //So time out is 5 seconds
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl"); //locally hosted
$array = $client->login(array('username'=>$username,
'password'=>$password));
$result = $array->return;
}catch(SoapFault $client){
$result = "0";
}
if($result == "true")//as this would be what the ws returns if login success
{
$_SESSION['user'] = $login;
echo "00";
}
else
{
echo "01 error: login failed";
}
?>
答案 0 :(得分:27)
2018年7月更新
如果您不关心获取SoapFault详细信息并且只想捕获来自SoapClient的任何错误,您可以在PHP 7+中捕获“Throwable”。最初的问题是SoapClient在抛出SoapFault之前可以“致命错误”,因此通过使用Throwable捕获错误和异常,您将获得非常简单的错误处理,例如。
try{
soap connection...
}catch(Throwable $e){
echo 'sorry... our service is down';
}
如果您需要专门捕获SoapFault,请尝试原始答案,该答案应该允许您抑制阻止SoapFault被抛出的致命错误
原始回答
虽然打开上面评论中提到的异常是处理解析错误的一个很好的步骤,但它本身是不够的,因为使用本机php函数SOAP可能会导致致命错误。
首先,您需要打开异常处理:
try {
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => true,
));
} catch ( SoapFault $e ) { // Do NOT try and catch "Exception" here
echo 'sorry... our service is down';
}
然后你还需要使用自定义错误处理程序静默抑制源自SOAP的任何“PHP错误”:
set_error_handler('handlePhpErrors');
function handlePhpErrors($errno, $errmsg, $filename, $linenum, $vars) {
if (stristr($errmsg, "SoapClient::SoapClient")) {
error_log($errmsg); // silently log error
return; // skip error handling
}
}
然后您将找到它,而不是使用正确的消息“Soap错误:SOAP-ERROR:解析WSDL:无法从'...'加载”来跳过SoapFault异常,因此您最终返回到catch语句中能够更有效地处理错误。
答案 1 :(得分:19)
Fatal error: SOAP-ERROR: Parsing WSDL
意味着WSDL错了,可能会丢失?所以它与肥皂无关。并且您无法通过try catch处理FATAL ERROR。请看这个链接:http://ru2.php.net/set_error_handler#35622
当您尝试在浏览器中访问http://192.168.0.142:8080/services/Logon?wsdl时,您会得到什么?
您可以检查WSDL是否像这样存在
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
/* You don't have a WSDL Service is down. exit the function */
}
curl_close($handle);
/* Do your stuff with SOAP here. */
答案 2 :(得分:7)
不幸的是,当服务关闭/无法访问而不是返回SoapFault对象时,SOAP会抛出致命错误。
话虽如此,您可以将其设置为抛出异常。您可能省略了将例外soap_client选项设置为false
的部分$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => false, // change to true so it will throw an exception
));
服务中断时捕获异常:
try {
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => true,
));
}
catch ( Exception $e )
{
echo 'sorry... our service is down';
}
答案 3 :(得分:2)
也许是更好的选择:
set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');
function my_exception_handler($e) {
exit('Error, something went terribly wrong: '.$e);
}
function my_error_handler($no,$str,$file,$line) {
$e = new ErrorException($str,$no,0,$file,$line);
my_exception_handler($e);
}
您可以在上述功能中调整错误消息。 我用它来回复你所做同样情况的信息,因为它可以随时发生。
假设您在初次登录后发送了一条肥皂消息,并且该响应永远不会到达或仅部分到达,这样您就可以返回没有任何脚本路径,名称和编号的消息。 在这种情况下,我根本不会返回$ e,而是输出类似的内容:'出了问题,请再试一次(稍后)。'
答案 4 :(得分:1)
我最终是这样处理的:
libxml_use_internal_errors(true); $sxe = simplexml_load_string(file_get_contents($url)); if (!$sxe) { return [ 'error' => true, 'info' => 'WSDL does not return valid xml', ]; } libxml_use_internal_errors(false);
检查后再打个电话。
答案 5 :(得分:0)
事实证明一切都很简单-使用名称空间时,请确保指定根ns!
那些< script language = "javascript"
type = "text/javascript" >
function iFrameHeight() {
var h = 0;
if (!document.all) {
h = document.getElementById('blockrandom').contentDocument.height;
document.getElementById('blockrandom').style.height = h + 60 + 'px';
} else if (document.all) {
h = document.frames('blockrandom').document.body.scrollHeight;
}
} < /script>
< div > Tesseramento al Torneo Campioni di Amicizia < /div> < iframe onload = "iFrameHeight()"
id = "blockrandom"
name = "iframe"
src = "https://app.softwaretessere.it/index.aspx"
width = "300%"
height = "1000"
scrolling = "no"
align = "top"
frameborder = "0" >
Questa scelta non funziona correttamente in quanto il browser utilizzato non supporta gli Inline Frames < /iframe>
-错误,正确的方法catch (SoapFailt $fault)
答案 6 :(得分:-8)
SoapFault不会扩展Exception,捕获特定类型的工作:
try {
$client = new SoapClient("http://192.168.0.142:8080/services/Logon?wsdl",array(
'exceptions' => true,
));
}
catch ( SoapFault $e )
{
echo 'sorry... our service is down';
}