web-dev-qa-db-fra.com

SOAP PHP erreur d'analyse WSDL: échec du chargement de l'entité externe?

J'essaie de faire fonctionner un service Web avec PHP & SOAP, mais tout ce que j'obtiens jusqu'ici, c'est ceci:

(SoapFault) [2] message indiquant: 'SOAP-ERROR: Parsing WSDL: Impossible de charger à partir de' http: //localhost/MyRegistration/login.xml ': impossible de charger l'entité externe " http : //localhost/MyRegistration/login.xml "

J'ai essayé de remplacer localhost par 127.0.0.1, mais cela ne fait aucune différence. login est en fait un fichier wsdl, mais si je mets login.wsdl dans le constructeur SOAPClient, le message "" semble ne pas avoir de document XML "". 

Voici mon code pour le client SOAP (register_client.php):

<?php
try
{
    $sClient = new SoapClient('http://127.0.0.1/MyRegistration/login.wsdl');    

    $param1 = $_POST["regname"];
    $param2 = $_POST["regpass1"];

    $response = $sClient->loginVerify($param1, $param2);    

    var_dump($response);
}
catch(SoapFault $e)
{
    var_dump($e);
}
?> 

Et voici le fichier login.wsdl:

<?xml version="1.0"?>
<definitions name="LoginVal" 
    targetNamespace="urn:LoginVal" 
    xmlns:tns="urn:LoginVal"  
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns="http://schemas.xmlsoap.org/wsdl/">
  <types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Login">
  <xsd:element name="getName" type="xsd:string" />
<xsd:element name="getPass" type="xsd:string" />
  <xsd:element name="LoginResponse" type="xsd:string" />          
</xsd:schema>           
  </types>

  <message name="loginVerify">
<part name="username" type="tns:getName" />
<part name="password" type="tns:getPass" />
  </message>

  <message name="doLoginResponse">
<part name="return" type="tns:LoginResponse" />
  </message>  

  <portType name="LoginPort">
    <operation name="loginVerify">
  <input message="tns:loginVerify" />
  <output message="tns:doLoginResponse" />
    </operation>
  </portType>

  <binding name="LoginBinding" type="tns:LoginPort">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
  <operation name="loginVerify">
    <soap:operation soapAction="urn:LoginAction" />
    <input>
      <soap:body use="encoded" namespace="urn:Login" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />         
    </input>
    <output>
      <soap:body use="encoded" namespace="urn:Login" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />         
    </output>
  </operation>
  </binding>

  <service name="LoginService">
    <port name="LoginPort" binding="tns:LoginBinding">
  <soap:address location="http://localhost/MyRegistration/register.php" />
    </port>
  </service>

</definitions>

Et je ne suis pas sûr que cela soit impliqué, je fournis donc le code pour le serveur SOAP register.php:

<?php
if(!extension_loaded("soap"))
{
    dl("php_soap.dll");
}

ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("login.wsdl", array('uri'=>'http://127.0.0.1/MyRegistration'))

public function loginVerify($username, $password)
{
    if($_POST["regname"] && $_POST["regemail"] && $_POST["regpass1"] && $_POST["regpass2"] )
    {
        if($_POST["regpass1"] == $_POST["regpass2"])
        {
            $servername = "localhost";
            $username = "root";
            $password = "Hellfire";

            $conn = mysql_connect($servername,$username,"Hellfire")or die(mysql_error());

            mysql_select_db("soap",$conn);

            $sql = "insert into users (name,email,password)values('$_POST[regname]','$_POST[regemail]','$_POST[regpass1]')";

            $result = mysql_query($sql,$conn) or die(mysql_error());

            return "You have registered sucessfully";

            //print "<a href='index.php'>go to login page</a>";
        }
        else return "passwords dont match";
    }
    else return "invalid data";
}

$server->AddFunction("loginVerify");
$server->handle();
?>

Je suis désolé si je fournis des informations inutiles, mais je suis un novice complet dans ce domaine - et j’apprécierais vraiment si quelqu'un pouvait dire pourquoi exactement cette SOAP faute est générée, et ce que je peut faire pour le rectifier. 

J'utilise WAMP Server version 2.2, avec MySQL 5.5.24 et PHP 5.3.13.

15
user1743679

Après avoir migré vers PHP 5.6.5, le soap 1.2 ne fonctionnait plus. J'ai donc résolu le problème en ajoutant des paramètres SSL facultatifs.

Mon erreur:

impossible de charger l'entité externe

Comment résoudre:

// options for ssl in php 5.6.5
$opts = array(
    'ssl' => array(
        'ciphers' => 'RC4-SHA',
        'verify_peer' => false,
        'verify_peer_name' => false
    )
);

// SOAP 1.2 client
$params = array(
    'encoding' => 'UTF-8',
    'verifypeer' => false,
    'verifyhost' => false,
    'soap_version' => SOAP_1_2,
    'trace' => 1,
    'exceptions' => 1,
    'connection_timeout' => 180,
    'stream_context' => stream_context_create($opts)
);

$wsdlUrl = $url . '?WSDL';
$oSoapClient = new SoapClient($wsdlUrl, $params);
24
Rômulo Z. C. Cunha

Placez ce code au-dessus de tout appel à Soap:

libxml_disable_entity_loader(false);
6
Nguyen Thanh

Sur register_client.php, assurez-vous que l'URL transmise à SoapClient est accessible à partir de la machine sur laquelle vous exécutez le code.

$sClient = new SoapClient('http://127.0.0.1/MyRegistration/login.wsdl');    

Si 127.0.0.0 ne fonctionne pas, vous pouvez essayer d'utiliser une adresse IP réseau et voir.

Faites-moi savoir si cela ne résout toujours pas le problème pour vous, j'ai essayé avec votre exemple et le changement de chemin (le rendant approprié dans mon environnement de développement) a corrigé la même erreur pour moi.

Je serais intéressé de savoir si cela ne résout pas le problème pour vous.

3
deej

J'ai eu le même problème.

Ce paramètre php a résolu mon problème: 

allow_url_fopen -> 1
2
hazard16

essaye ça. travaille pour moi

$options = array(
    'cache_wsdl' => 0,
    'trace' => 1,
    'stream_context' => stream_context_create(array(
          'ssl' => array(
               'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
          )
    ))

$client = new SoapClient(url, $options);
2
gogagubi

Vous avez obtenu une réponse similaire avec une URL https WSDL utilisant php soapClient

Exception SoapFault: [WSDL] SOAP-ERROR: Analyse de WSDL: Impossible de charger à partir de ...

Après la mise à jour du serveur à partir de PHP 5.5.9-1ubuntu4.21 >> PHP 5.5.9-1ubuntu4.23, une erreur s'est produite sur ma machine cliente osx 10.12.6/PHP 5.6 .30, mais les connexions des clients des services Web MS peuvent se faire sans problème.

Server_access.log d'Apache2 n'a indiqué aucune entrée lorsque j'ai essayé de charger WSDL; j'ai donc ajouté 'cache_wsdl' => WSDL_CACHE_NONE pour empêcher la mise en cache wsdl côté client, mais je n'ai toujours aucune entrée. Enfin, j'ai essayé de charger wsdl par CURL -i vérifié HEADERS mais tout semblait aller pour le mieux.

Seul libxml_get_last_error() a fourni des informations> SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

J'ai donc ajouté quelques options ssl à mon appel:

$contextOptions = array(
    'ssl' => array(
    'verify_peer' => false,
    'verify_peer_name' => false,
    'allow_self_signed' => true
    ));

$sslContext = stream_context_create($contextOptions);

$params =  array(
    'trace' => 1,
    'exceptions' => true,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'stream_context' => $sslContext
    );

try {
    $proxy = new SoapClient( $wsdl_url, $params );
} catch (SoapFault $proxy) {
    var_dump(libxml_get_last_error());
    var_dump($proxy);
}

Dans mon cas, 'allow_self_signed' => true a fait l'affaire!

1
c3labs

Si tout le monde a le même problème, une solution possible consiste à définir le paramètre de configuration du contexte de flux bindto (en supposant que vous vous connectiez de 11.22.33.44 à 55.66.77.88):

$context = [
    'socket' => [
        'bindto' => '55.66.77.88'
    ]
];

$options = [
    'soapVersion' => SOAP_1_1,
    'stream_context' => stream_context_create($context)
];

$client = new Client('11.22.33.44', $options);
0
Shmarkus