Das Deutsche PHP Forum

Einklappen
Keine Ankündigung bisher.

Das Deutsche PHP Forum

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Php - soap - delphi

    @all

    Ich möchte voarausschicken, das meine PHP Kentnisse im Gegensatz zu meinen Delphi Kenntnissen weit zurückstehen und wahrscheinlich aus diesem Grunde meine Schwierigkeiten resultieren.

    Zum Problem:

    Ich möchte einen PHP-Webservice erstellen und mit einem Delphi-Client ansprechen.

    Zu diesem Zweck habe ich eine WSDL-Datei generiert (erledigt Delphi automatisch) einen Webservice sowie einen Client in Delphi geschrieben und die Funktion überprüft.

    Dann habe ich die Umsetzung als PHP-Webservice in Angriff genommen, aber leider erhalte ich nur folgenden Response:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>looks like we got &quot;Body&quot; with several functions call</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
    Der Request der an den Service gerichtet ist:

    Code:
    Soap-Method: Signup
    <?xml version="1.0"?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS2="urn:FloSrvIntf"><NS1:Signup xmlns:NS1="urn:FloSrvIntf-IFloSrv"><SignupData href="#1"/></NS1:Signup><NS2:TSignupData id="1"><Username>Test</Username><Password>NoPassword</Password></NS2:TSignupData></SOAP-ENV:Body></SOAP-ENV:Envelope>
    Die zugehörige WSDL-Datei:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" name="IFloSrvservice" targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns1="urn:FloSrvIntf">
      <types>
        <xs:schema targetNamespace="urn:FloSrvIntf" xmlns="urn:FloSrvIntf">
          <xs:complexType name="TSignupData">
            <xs:sequence>
              <xs:element name="Username" type="xs:string"/>
              <xs:element name="Password" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:schema>
      </types>
      <message name="Signup0Request">
        <part name="SignupData" type="ns1:TSignupData"/>
      </message>
      <message name="Signup0Response">
        <part name="return" type="xs:boolean"/>
      </message>
      <portType name="IFloSrv">
        <operation name="Signup">
          <input message="tns:Signup0Request"/>
          <output message="tns:Signup0Response"/>
        </operation>
      </portType>
      <binding name="IFloSrvbinding" type="tns:IFloSrv">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="Signup">
          <soap:operation soapAction="urn:FloSrvIntf-IFloSrv#Signup" style="rpc"/>
          <input message="tns:Signup0Request">
            <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:FloSrvIntf-IFloSrv"/>
          </input>
          <output message="tns:Signup0Response">
            <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:FloSrvIntf-IFloSrv"/>
          </output>
        </operation>
      </binding>
      <service name="IFloSrvservice">
        <port name="IFloSrvPort" binding="tns:IFloSrvbinding">
          <soap:address location="http://localhost/flo/TestServer.php"/>
        </port>
      </service>
    </definitions>
    Die Delphi Typendeclaration des complexen Datentyps (automatisch generiert):

    Code:
      // ************************************************************************ //
      // Namespace : urn:FloSrvIntf
      // ************************************************************************ //
      TSignupData = class(TRemotable)
      private
        FUsername: WideString;
        FPassword: WideString;
      published
        property Username: WideString read FUsername write FUsername;
        property Password: WideString read FPassword write FPassword;
      end;

    Der PHP-Webservice:

    Code:
    <?php
    
      $Wsdl = 'http://localhost/flo/FloSrv.wsdl';
      $Signup = array("Username" => "", "Password" => "");
      function Signup($Signup)
      {
        if ($Signup["Username"] == "ValidatedName")
        {
          Return True;
        }
        else
        {
          Return False;
        }
      }
      ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
      $server = new SoapServer($Wsdl);
      $server->addFunction("Signup");
      $server->handle();
    ?>
    Bei einfachen Datentypen wie Strings, Integer oder ähnliches funktioniert alles einwandfrei. Das Problem liegt meiner Vermutung nach im Complexen Datentyp.

    Schon einmal ein herzliches Dankeschön vorab für eure Hilfe.

    Highway

  • #2
    hi,

    worin genau liegt nun dein problem ?

    das du z.b. keine complexen datentypen darüber schicken kannst ?

    greetings,
    warl0rd

    Kommentar


    • #3
      @warl0rd

      Exakt! Das ist genau das Problem.

      Kommentar


      • #4
        hi,

        um z.b. ein array per webservices zu übertragen solltest do folgendes machen....

        Code:
        <?php
        
        function GETstmt( $sql )
        {
        	$data = "";
        	$result = "";
        	
        	$db_host = "";	
        	$db_user = "";
        	$db_pass = "";
        	$db      = "";
        	
        	$conn  = mysql_connect( $db_host, $db_user, $db_pass );
        	mysql_select_db( $db );
        	$query = mysql_query( $sql );
        	
        	$i=0;
            	while( $result = mysql_fetch_object( $query ))
            	{
               		$data[$i] = $result;
               		$i++;
            	}
                return $data;
        }
        
        include( "soap/Server.php" );
        $server  = new SOAP_Server();
        $server->_auto_translation = TRUE;
        $service = new Service();
        $server->addObjectMap( $service, "urn:soapservice");
        
        if( isset( $_SERVER["REQUEST_METHOD"] ) && 
                   $_SERVER["REQUEST_METHOD"] == "POST" )
        {
        	$server->Service( $HTTP_RAW_POST_DATA );
        }
        else
        {
        	include( "soap/Disco.php" );
        	$disco = new SOAP_DISCO_Server( $server, "Bezeichnung" );
        	if( isset( $_SERVER["QUERY_STRING"] ) && 
        	strcasecmp( $_SERVER["QUERY_STRING"], "wsdl" ) == 0 )
        	{
        		header("Content-type: text/xml");
        		print $disco->getWSDL();
        	}
        }
        
        
        Class Service
        {
        	var $__dispatch_map = array();
        	var $data;
        	
        	function Service()
        	{
        		
        		$this->__dispatch_map["ShowNews"] =
        		array( "in"  => array( "id" => "string" ),
        		       "out" => array( "meldung" => "string" ) );
        	}
        	
        	function __dispatch( $methode )
        	{
        		if( isset( $this->__dispatch_map[ $methode ] ) )
        		{
        			return $this->__dispatch_map[ $methode ];
        		}
        		else
        		{
        			return NULL;
        		}	
        	}
        	
        		
        	function ShowNews( $id )
        	{
        		$data = GETstmt( "SELECT meldung FROM news WHERE id = '" . $id . "'" );
        		if( !$data )
        		{
        			return "Keinen Eintrag gefunden";
        		}
        		else
        		{
        			$ret->array = $data[0]->meldung;
        			return $ret;
        		}
        	}
        	
        
        } 
        
        ?>
        siehe bei der Funktion ShowNews() das return $ret; da wird vorher die Variable $ret->array mit einem Array gefüllt....

        hab dir mal den meinen kompl. source geschickt damit man alles besser sehen kann...

        und die abfrage der funktion sieht dann in php so aus:

        Code:
        <?php
        
        include( "soap/Client.php" );
        $wsdl     = new SOAP_WSDL( "http://localhost/test/wsdlserver.php?wsdl" );
        $proxy    = $wsdl->getProxy();
        
        $news = $proxy->ShowNews( "1" );
        print( $news->array );
        
        ?>
        kopier dir am besten mal beide codeteile und spiel damit rum, ist im prinzip ganz einfach z.b. ein array oder ähnliches per WebService weiterzugeben oder zu verarbeiten...

        greetings,
        warl0rd

        Kommentar


        • #5
          @warl0rd

          Erst mal herzlichen Dank.

          Mich beschleicht aber das Gefühl, dass wir ein wenig aneinander vorbeireden.

          Ich habe nicht erwähnt, das ich PHP 5 benutze (native SOAP support).

          Den Code den du gepostet hast sieht mir nach PHP 4 Code aus wenn ich mich nicht irre.

          Vielleicht hilft die Fehlermeldung weiter:


          looks like we got "Body" with several functions call
          Unklar ist auch warum die Konstellationen:

          Delphi-Service / Delphi-Client - funktioniert
          Delphi-Service / PHP-Client - funktioniert
          PHP-Service / PHP-Client - funktioniert
          PHP-Service / Delphi-Client - FEHLER (Bei komplexen Datentypen)
          PHP-Service / Delphi-Client - funktioniert (Bei einfachen Datentypen)

          und das wohlgemerkt immer mit der gleichen WSDL-Datei.

          Ich habe auch mit Absicht nichts relevantes hart kodiert, damit es mit der Definition der Datentype keinen Ärger gibt.

          Das der Fehler im Delphi-Client liegt ist eher unwahrscheinlich, da er in Verbindung mit dem Delphi-Service und auch fremden, im Netz stehenden, Werservices funktioniert. (Auch mit komplexen Datentypen)

          Ich gehe fest von einer missinterpretation der Daten im PHP-Service aus, weil ich da etwas falsch gemacht habe.

          Ich habe im obenstehenden Posting den SOAP-Request gepostet. Kann aber keinen Fehler entdecken. Das ist für mich SOAP Konform.

          Trotzdem weißt der PHP-Service den Request mit einer Fehlermeldung ab!?

          Da hänge ich nun schon seit 3 Tagen dran und finde keine Lösung, auch nicht im Netz.

          Kommentar

          Lädt...
          X