web-dev-qa-db-fra.com

PHP SOAP erreur de capture

Je commence à désespérer, tout ce que je veux, c'est une simple gestion des erreurs lorsque le service Web PHP SOAP doit renvoyer un message d'erreur service de connexion désactivé . Aidez-moi, s'il vous plaît!

Pour le moment, l'erreur est toujours affichée (avec les avertissements ...):

Fatal error: SOAP-ERROR: Parsing WSDL 

Voici le 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";
}
?>
22
David

MISE À JOUR Juillet 2018

Si vous ne vous souciez pas d'obtenir les détails de SoapFault et que vous voulez juste récupérer les erreurs provenant de SoapClient, vous pouvez capturer "Throwable" dans PHP 7+. Le problème initial était que SoapClient peut "Erreur fatale" avant de lancer un SoapFault. Ainsi, en interceptant les erreurs et les exceptions avec Throwable, vous aurez un traitement très simple des erreurs, par exemple.

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

Si vous avez besoin d'attraper spécifiquement SoapFault, essayez la réponse d'origine qui devrait vous permettre de supprimer l'erreur fatale empêchant le lancement de SoapFault.

Réponse originale

Tandis que l'activation des exceptions mentionnées dans le commentaire ci-dessus est une bonne étape pour gérer les erreurs d'analyse, cela ne suffit pas en soi, car SOAP peut provoquer une erreur fatale en utilisant les fonctions natives de php.

Donc, vous devez d’abord activer la gestion des exceptions:

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

ET ALORS, vous devez également supprimer en mode silencieux les «erreurs PHP» provenant de SOAP à l'aide d'un gestionnaire d'erreurs personnalisé:

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

Vous le trouverez alors maintenant et déclenche une exception SoapFault avec le message correct "Erreur SOAP: SOAP-ERROR: Analyse de WSDL: Impossible de charger à partir de '...'" et vous vous retrouvez donc dans votre instruction catch capable de gérer l'erreur plus efficacement.

26
MeatPopsicle

Fatal error: SOAP-ERROR: Parsing WSDL signifie que le WSDL est faux et peut-être manquant? donc ce n'est pas lié au savon. Et vous ne pouvez pas gérer FATAL ERROR avec un catch try. Voir ce lien: http://ru2.php.net/set_error_handler#35622

Qu'est-ce que vous obtenez lorsque vous essayez d'accéder à http://192.168.0.142:8080/services/Logon?wsdl dans votre navigateur?

Vous pouvez vérifier si le WSDL est présent comme ceci 

$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. */
19
yokoloko

Malheureusement, SOAP renvoie une erreur fatale lorsque le service est arrêté/inaccessible plutôt que de renvoyer un objet SoapFault.

Cela étant dit, vous pouvez le configurer pour lancer une exception. Vous avez probablement omis la partie où vous définissez l'option exceptions soap_client sur 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
));

Catch l'exception lorsque le service est en panne:

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';
}
6
Brad Kent

Peut-être une meilleure alternative:

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

Où vous pouvez ajuster les messages d'erreur dans les fonctions mentionnées .. Je l'utilise pour retourner un message dans la même situation que vous, car il peut survenir à tout moment.

Supposons que vous envoyiez un message soap après la connexion initiale, et que cette réponse n'arrive jamais ou arrive partiellement, ainsi vous pouvez renvoyer un message sans chemin de script, nom ni numéro de dossier . Dans ce cas, je ne retourne pas $ e à tous, au lieu de cela, je viens de sortir quelque chose comme: 'Quelque chose ne va pas, s'il vous plaît essayez à nouveau (plus tard).'

2
Jonathan

J'ai fini par le manipuler de cette façon:

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

Faites votre appel de savon après cette vérification.

1
Aurimas Rekštys