Come catturare i dati dal contenuto XML di una richiesta di sapone in un PHP Sowapserver?

StackOverflow https://stackoverflow.com//questions/12692797

  •  12-12-2019
  •  | 
  •  

Domanda

Sto cercando di impostare un servizio di sapone in PHP. Ho dichiarato una funzione PHP del server e sono in grado di chiamare quella funzione con una richiesta HTTP di tipo SOAP in cui il contenuto è la mia busta di sapone.

Il contenuto XML del corpo sapone è l'argomento della funzione che presumo, ma non so come accedere alle informazioni in esso nel mio codice PHP.

Ho notato che l'argomento funzione è un'istanza di stdClass per impostazione predefinita, e in realtà mi chiedo perché non viene lanciato su un oggetto XML o DOM da Php - è una chiamata di sapone, non è vero? Ma va tutto bene, ora dipende da me per ottenere le informazioni fuori dall'oggetto, che non è facile perché non ci sono metodi assegnati a stdClass, quindi dovrà essere funzioni PHP standard. Così ho provato serialize, ma questo mi ha dato un po 'di spazzatura, non la corda XML che mi aspettavo.

Cosa fare?

Modifica

Si noti che di seguito non ha alcun codice di esempio di ciò che desidero fare - ottenere alcuni dati di dettaglio dal contenuto XML della richiesta SOAP - perché non so come il codice di prenderlo dall'oggetto STDClass

Su richiesta di David, ecco alcuni dettagli.

Codice PHP:

<?php
    function mi102($arg) {
        $txt = serialize ($arg);
        $result = new SoapVar ($txt, XSD_ANYXML);
        return($result);
    }
    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("test.wsdl");
    $server -> addFunction ("mi102");
    try {
        $server -> handle();
    }
    catch (Exception $e) {
        $server -> fault ('Client', $e -> getMessage());
    }
?php>
.

La richiesta HTTP è costruita da un'applicazione che uso; L'intestazione HTTP e il corpo involucro sapone + sono generati attorno all'XML I Feed IT:

Contenuto del corpo di richiesta del sapone:

<mi102 xmlns="http://pse">
  <cdhead cisprik="21"/>
  <instr>
    <insid>
      <bcdt>20120930</bcdt>
    </insid>
  </instr>
</mi102>
.

L'WSDL utilizzato è il seguente:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://pse/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="PSE" targetNamespace="http://pse/">
    <types>
        <xs:schema>
            <xs:import namespace="http://pse/" schemaLocation="PSE.xsd"/>
        </xs:schema>
    </types>
    <message name="MI102Req">
        <part name="cdhead" type="tns:cdhead_T"/>
        <part name="instr" type="tns:instr_T"/>
    </message>
    <message name="Res">
        <part name="cdhead" type="tns:cdhead_T"/>
    </message>
    <portType name="MIPortType">
        <operation name="mi102">
            <input message="tns:MI102Req"/>
            <output message="tns:Res"/>
        </operation>
    </portType>
    <binding name="MIBinding" type="tns:MIPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="mi102">
            <soap:operation soapAction="http://testServerURL/test_soap.php#mi102"/>
            <input>
                <soap:body use="literal" namespace="http://pse/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://pse/"/>
            </output>
        </operation>
    </binding>
    <service name="PSE">
        <port name="MIPortType" binding="tns:MIBinding">
            <soap:address location="http://testServerURL/test_soap.php"/>
        </port>
    </service>
</definitions>
.

E il XML risultante (di nuovo, estratto dal corpo di sapone da parte dell'applicazione che uso), è

Risposta del sapone:

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mi102Response xmlns:ns1="http://pse/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">O:8:"stdClass":2:{s:7:"cisprik";i:21;s:7:"version";s:2:"13";}</ns1:mi102Response>
.

Non è carino.

È stato utile?

Soluzione

Alla fine ho trovato la risposta in altri thread su così, come riceviti-xml-da-php-soap-server

La soluzione è utilizzare quanto segue:

$inp = file_get_contents ('php://input');
.

Nota: non ho trovato alcuna funzione che può agire sull'argomento di ingresso stdClass e può recuperare i contenuti del corpo di sapone XML da esso.

Quindi l'opzione migliore è utilizzare la variabile di ingresso PHP standard.Si noti che questo ha la seguente struttura: Envelope/Body/..inputXML.., che è il contenuto esatto della richiesta HTTP che è pubblicato sul server.

Nota: http_get_request_body può funzionare anche, ma il mio server PHP non ha supportato questa funzione.Penso che file_get_contents sia supportato su ogni server PHP da qualche versione in poi.

Altri suggerimenti

Questo non inizierà come risposta completa, ma volevo la formattazione. Si prega di elaborare su ciò che hai impostato. Generalmente, avrai un metodo PHP con argomenti regolari (non XML) che si desidera esporre come servizio web. Un esempio di base su come fare questo è qui:

http://www.phpeveryday. COM / Articoli / Servizi Web-Services-WSDL-Creazione-sapone-server-P484.html

.

Il contenuto XML del corpo sapone è l'argomento della funzione che presumo

No, il contenuto XML del corpo sapone è la rappresentazione del metodo con i tuoi argomenti, ma i tuoi argomenti sono quello che vuoi. Non dovresti gestire manualmente XML se lo si imposta con PHP So Shapserver e SOACCLEND.

Modifica: stai assumendo la tua argomentazione, che è una semplice rappresentazione di array PHP del corpo della tua richiesta di sapone, serializzandolo e inviandolo come risposta (che è ciò che osservi). È questo ciò che vuoi fare? Non vuoi fare qualcosa con i dati della richiesta? Inoltre, puoi pubblicare lo schema che è importato dal WSDL?

Stai avendo la rappresentazione "non carina" di un oggetto perché stai restituendo l'oggetto serializzato (la serializzazione sta convertendo l'oggetto e il suo stato in una rappresentazione di stringa). Se si desidera avere una rappresentazione XML dell'oggetto restituito, è necessario modificare il tipo di parametro di ritorno della funzione su un oggetto. Perché ora sta tornando una stringa.

Ti consiglierei di utilizzare i componenti Zend_soap_server e zend_soap_autodiscover del framework Zend.

con zend_soap_autodiscover È possibile generare la definizione del servizio web (WSDL) dinamicamente, solo scrivendo i documenti delle tue funzioni. E zend_soap_server è anche bello anche.

Se si utilizzano tali componenti e documenta i tipi e la funzione per restituire un tipo specifico senza serializzazione, riceverai la rappresentazione XML in base alla definizione WSDL. Inoltre, ciascun tipo che si crea viene automaticamente convertito da zend_soap_autodiscover a una complessità in WSDL generato.

Esempio:

 public class Person{
         public $id;
         public $name;
    }

    public class MyService {
     /**
     *
     * @param integer $UserID
     * @return Person
     */
    function mi102($UserID) {

         $output = new Person();
         $output->id = 2;
         $output->name = 'Peter';        

        return $output;
    }
}


// Generate WSDL relevant to code
if (isset($_GET['wsdl'])){

    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('MyService');
    $autodiscover->handle();

} else {

    $server = new Zend_Soap_Server($serviceURL . "?wsdl");
    $server->setClass('MyService');
    $server->setObject(new MyService());
    $server->handle();

}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top