Подтвердить что ты не робот

Устранение ошибок PHP SOAP

Я получаю отчаяние, все, что мне нужно, - это простая обработка ошибок, когда веб-служба PHP SOAP отключена, чтобы эхо-сообщение об ошибке было зарегистрировано. Пожалуйста, помогите мне!

В настоящий момент все еще отображается ошибка (наряду с предупреждениями):

Fatal error: SOAP-ERROR: Parsing WSDL

Вот script:

<?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";
}
?>
4b9b3361

Ответ 1

ОБНОВЛЕНИЕ июль 2018

Если вас не интересует получение сведений о SoapFault и вы просто хотите отследить любые ошибки, возникающие в SoapClient, вы можете перехватить "Throwable" в PHP 7+. Первоначальная проблема заключалась в том, что SoapClient может "Fatal Error" до того, как он генерирует SoapFault, поэтому, перехватывая как ошибки, так и исключения с помощью Throwable, вы будете иметь очень простую обработку ошибок, например,

try{
    soap connection...
}catch(Throwable $e){
    echo 'sorry... our service is down';
}

Если вам нужно специально перехватить SoapFault, попробуйте исходный ответ, который позволит вам устранить фатальную ошибку, которая предотвращает выброс SoapFault

Оригинальный ответ актуален для более старых версий PHP

SOAP может привести к фатальной ошибке, вызывая внутренние функции php изнутри, что предотвращает выброс SoapFaults, поэтому нам необходимо регистрировать и подавлять эти собственные ошибки.

Сначала вам нужно включить обработку исключений:

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';
}

И затем вам также нужно молча подавлять любые "ошибки PHP", возникающие из SOAP, с помощью специального обработчика ошибок:

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
    }
}

Затем вы обнаружите, что теперь он вместо этого отключает исключение SoapFault с правильным сообщением "Ошибка мыла: SOAP-ERROR: синтаксический анализ WSDL: невозможно загрузить из"..."", и поэтому вы в конечном итоге возвращаетесь в свой оператор catch в состоянии обработать ошибку более эффективно.

Ответ 2

Fatal error: SOAP-ERROR: Parsing WSDL Значит, WSDL ошибочен и, возможно, отсутствует? поэтому он не относится к мылу. И вы не можете справиться с FATAL ERROR с помощью try catch. См. Эту ссылку: 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. */

Ответ 3

К сожалению, SOAP вызывает фатальную ошибку, когда служба недоступна/недоступна, а не возвращает объект SoapFault.

При этом вы можете настроить его для исключения исключений. Вероятно, вы опустили ту часть, где вы устанавливаете опцию 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';
}

Ответ 4

Возможно, лучшая альтернатива:

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);
}

Где вы можете настроить сообщения об ошибках в указанных функциях. Я использую его для возврата сообщения в той же ситуации, что и вы, поскольку это может произойти в любое время.

Скажите, что вы отправили сообщение о мыле после первоначального входа в систему, и этот ответ никогда не приходит или не приходит только частично, таким образом вы можете вернуть сообщение без каких-либо script путей, имен и прошивок. В таких случаях я вообще не возвращаю $e, вместо этого я просто выводил что-то вроде: "Что-то пошло не так, попробуйте еще раз (позже)".

Ответ 5

Я закончил с этим так:

       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);

Сделайте свой мыльный звонок после этой проверки.

Ответ 6

Все оказалось гораздо более тривиальным - при использовании пространств имен обязательно указывайте root ns! Те, кто catch (SoapFailt $fault) - неправильно, правильный путь catch (\ SoapFault $fault)

Ответ 7

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';
}