Frage

Ich versuche, einen SOAP-Dienst in PHP einzurichten.Ich habe eine Server-PHP-Funktion deklariert und kann diese Funktion mit einer HTTP-Anforderung vom SOAP-Typ aufrufen, bei der der Inhalt mein SOAP-Umschlag ist.

Der XML-Inhalt des SOAP-Körpers ist das Argument der Funktion, die ich annehme, aber ich weiß nicht, wie ich in meinem PHP-Code auf die darin enthaltenen Informationen zugreifen soll.

Mir ist aufgefallen, dass das Funktionsargument eine Instanz von ist stdClass standardmäßig, und ich frage mich tatsächlich, warum es nicht auf eine gegossen wird XML oder DOM objekt von PHP - es ist ein SOAP-Aufruf, nicht wahr?Aber in Ordnung, jetzt liegt es an mir, die Informationen aus dem Objekt herauszuholen, was nicht einfach ist, da keine Methoden zugewiesen sind stdClass, also muss es Standard-PHP-Funktionen sein.Also habe ich es versucht serialize, aber das gab mir etwas Müll, nicht die XML-Zeichenfolge, die ich erwartet hatte.

Was ist zu tun?

BEARBEITEN

beachten Sie, dass unten kein Beispielcode für das enthalten ist, was ich tun möchte - einige Detaildaten aus dem XML-Inhalt der SOAP-Anforderung abrufen -, da ich nicht weiß, wie ich sie aus dem stdClass-Objekt abrufen soll

Auf Anfrage von David, hier einige Details.

php Programmierung:

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

die HTTP-Anfrage wird von einer Anwendung erstellt, die ich verwende;der HTTP-Header und der Soap-Umschlag + Body werden um das XML herum generiert, das ich ihm füttere:

Inhalt des SOAP-Anforderungskörpers:

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

Die verwendete WSDL lautet wie folgt:

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

Und das resultierende XML (wiederum von der von mir verwendeten Anwendung aus dem SOAP-Body extrahiert) lautet

SOAP-Antwort:

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

Nicht nett.

War es hilfreich?

Lösung

Ich habe die Antwort schließlich in anderen Threads auf SO gefunden, wie erhalte-empfangenes-xml-von-php-soap-server

Die Lösung besteht darin, Folgendes zu verwenden:

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

Beachten:Ich konnte keine Funktion finden, die auf die wirken kann stdClass eingabeargument und kann den XML-SOAP-Body-Inhalt daraus abrufen.
Die beste Option ist also die Verwendung der Standard-PHP-Eingabevariablen.Beachten Sie, dass dies die folgende Struktur hat: Envelope/Body/..inputXML.., Dies ist der genaue HTTP-Anforderungsinhalt, der an den Server gesendet wird.

Beachten: http_get_request_body kann auch funktionieren, aber mein PHP-Server hat diese Funktion nicht unterstützt.Ich denke, dass file_get_contents wird auf jedem PHP-Server ab einer bestimmten Version unterstützt.

Andere Tipps

Dies wird nicht als vollständige Antwort beginnen, aber ich wollte die Formatierung.Bitte erläutern Sie, was Sie eingerichtet haben.Im Allgemeinen verfügen Sie über eine PHP-Methode mit regulären Argumenten (nicht XML), die Sie als Webdienst verfügbar machen möchten.Ein grundlegendes Beispiel dafür ist hier:

http://www.phpeveryday.com/articles/Web-Services-WSDL-Creating-SOAP-Server-P484.html

Der XML-Inhalt des SOAP-Körpers ist das Argument der Funktion, die ich annehme

Nein, der XML-Inhalt des SOAP-Körpers ist der Darstellung von der Methode mit Ihren Argumenten, aber Ihre Argumente sind, was Sie wollen.Sie sollten sich nicht manuell mit XML befassen müssen, wenn Sie es mit PHPs SoapServer und SoapClient einrichten.

BEARBEITEN:Sie nehmen Ihr Argument, bei dem es sich um eine einfache PHP-Array-Darstellung des Hauptteils Ihrer SOAP-Anforderung handelt, serialisieren es und senden es als Antwort zurück (was Sie beobachten).Ist es das, was du tun willst?Möchten Sie mit den Anforderungsdaten nichts anfangen?Können Sie auch das Schema posten, das aus der WSDL importiert wurde?

Sie haben diese "nicht schöne" Darstellung eines Objekts, weil Sie das Objekt serialisiert zurückgeben (die Serialisierung konvertiert das Objekt und seinen Status in eine Zeichenfolgendarstellung).Wenn Sie eine XML-Darstellung des zurückgegebenen Objekts haben möchten, sollten Sie den Rückgabeparametertyp Ihrer Funktion in ein Objekt ändern.Weil jetzt eine Zeichenfolge zurückgegeben wird.

Ich würde Ihnen empfehlen, die Komponenten Zend_Soap_Server und Zend_Soap_Autodiscover des zend Frameworks zu verwenden.

Mit Zend_Soap_Autodiscover können Sie Ihre Web Service Definition (wsdl) dynamisch generieren, indem Sie einfach die Dokumentblöcke Ihrer Funktionen schreiben.Und Zend_Soap_Server ist auch ziemlich cool.

Wenn Sie diese Komponenten verwenden und Ihre Typen und Ihre Funktion dokumentieren, um einen bestimmten Typ zurückzugeben, ohne ihn zu serialisieren, erhalten Sie die XML-Darstellung gemäß der WSDL-Definition.Außerdem wird jeder Typ, den du erstellst, automatisch von Zend_Soap_Autodiscover in einen complexType in der generierten wsdl konvertiert.

Probe:

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

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top