2013-03-08 11 views
16

Sto provando a chiamare un metodo SOAP utilizzando PHP.Creazione di una chiamata SOAP utilizzando PHP con un corpo XML

Ecco il codice che ho:

$data = array('Acquirer' => 
    array(
    'Id' => 'MyId', 
    'UserId' => 'MyUserId', 
    'Password' => 'MyPassword' 
)); 
$method = 'Echo'; 
$client = new SoapClient(NULL, 
      array('location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler', 
      'uri' => 'http://example.com/wsdl', 'trace' => 1)); 
$result = $client->$method($data); 

Ecco la richiesta che crea:

<?xml version="1.0" encoding="UTF-8"?> 
    <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <ns1:Echo> 
     <param0 xsi:type="ns2:Map"> 
      <item> 
      <key xsi:type="xsd:string">Acquirer</key> 
      <value xsi:type="ns2:Map"> 
       <item> 
       <key xsi:type="xsd:string">Id</key> 
       <value xsi:type="xsd:string">mcp</value> 
       </item> 
       <item> 
       <key xsi:type="xsd:string">UserId</key> 
       <value xsi:type="xsd:string">tst001</value> 
       </item> 
       <item> 
       <key xsi:type="xsd:string">Password</key> 
       <value xsi:type="xsd:string">test</value> 
       </item> 
      </value> 
      </item> 
     </param0> 
     </ns1:Echo> 
    </SOAP-ENV:Body> 
    </SOAP-ENV:Envelope> 

Ed ecco cosa ho voglio la richiesta a guardare come:

<?xml version="1.0" encoding="UTF-8"?> 
    <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <Echo> 
     <Acquirer> 
      <Id>MyId</Id> 
      <UserId>MyUserId</UserId> 
      <Password>MyPassword</Password> 
     </Acquirer> 
     </Echo> 
    </SOAP-ENV:Body> 
    </SOAP-ENV:Envelope> 
+1

Questo non può essere risolto senza le informazioni WSDL complete disponibili. Il PHP SoapClient analizza attivamente e usa il WSDL per mettere gli argomenti della funzione nei posti giusti. Senza il WSDL caricato, è quasi impossibile creare qualcosa che funzioni. – Sven

+0

@Sven: è molto utile, anche se non risolve completamente il mio problema. Puoi postarlo come risposta? Se nessun altro risponde, lo accetterò almeno in quanto mi ha aiutato ad andare avanti un po '. – greggles

+0

No grazie, hai una risposta migliore che potrebbe meritare la generosità. – Sven

risposta

41

Ci sono un paio di modi per risolvere questo. Il meno hackiest e quasi ciò che si vuole:

$client = new SoapClient(
    null, 
    array(
     'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler', 
     'uri' => 'http://example.com/wsdl', 
     'trace' => 1, 
     'use' => SOAP_LITERAL, 
    ) 
); 
$params = new \SoapVar("<Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer>", XSD_ANYXML); 
$result = $client->Echo($params); 

In questo modo si ottiene il seguente codice XML:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com/wsdl"> 
    <SOAP-ENV:Body> 
     <ns1:Echo> 
      <Acquirer> 
       <Id>MyId</Id> 
       <UserId>MyUserId</UserId> 
       <Password>MyPassword</Password> 
      </Acquirer> 
     </ns1:Echo> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

che è quasi esattamente quello che vuoi, tranne che per lo spazio dei nomi del nome del metodo. Non so se questo è un problema. Se è così, puoi modificarlo ulteriormente. Si potrebbe mettere il tag <Echo> nella stringa XML a mano e hanno il SoapClient non impostato il metodo aggiungendo 'style' => SOAP_DOCUMENT, alla matrice di opzioni in questo modo:

$client = new SoapClient(
    null, 
    array(
     'location' => 'https://example.com/ExampleWebServiceDL/services/ExampleHandler', 
     'uri' => 'http://example.com/wsdl', 
     'trace' => 1, 
     'use' => SOAP_LITERAL, 
     'style' => SOAP_DOCUMENT, 
    ) 
); 
$params = new \SoapVar("<Echo><Acquirer><Id>MyId</Id><UserId>MyUserId</UserId><Password>MyPassword</Password></Acquirer></Echo>", XSD_ANYXML); 
$result = $client->MethodNameIsIgnored($params); 

Il risultato è la seguente richiesta XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Body> 
     <Echo> 
      <Acquirer> 
       <Id>MyId</Id> 
       <UserId>MyUserId</UserId> 
       <Password>MyPassword</Password> 
      </Acquirer> 
     </Echo> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Infine, se vuoi giocare con gli oggetti SoapVar e SoapParam, puoi trovare un buon riferimento in questo commento nel manuale PHP: http://www.php.net/manual/en/soapvar.soapvar.php#104065. Se riesci a farlo funzionare, faccelo sapere, ho fallito miseramente.

8

Prima di tutto, è necessario specificare che si desidera utilizzare lo stile del documento letterale:

$client = new SoapClient(NULL, array(
    'location' => 'https://example.com/path/to/service', 
    'uri' => 'http://example.com/wsdl', 
    'trace' => 1, 
    'use' => SOAP_LITERAL) 
); 

Quindi, è necessario per trasformare i dati in un SoapVar; Ho scritto una semplice funzione di trasformazione:

function soapify(array $data) 
{ 
     foreach ($data as &$value) { 
       if (is_array($value)) { 
         $value = soapify($value); 
       } 
     } 

     return new SoapVar($data, SOAP_ENC_OBJECT); 
} 

Quindi, è diffusa questa funzione di trasformazione sul vostro dati:

$data = soapify(array(
    'Acquirer' => array(
     'Id' => 'MyId', 
     'UserId' => 'MyUserId', 
     'Password' => 'MyPassword', 
    ), 
)); 

Infine, viene chiamato il servizio passando il parametro Dati:

$method = 'Echo'; 

$result = $client->$method(new SoapParam($data, 'Data')); 
+0

Questo è in realtà il primo post sullo stackoverlow che ha menzionato il parametro "Dati" –