Stella L.: keine Rückgabe bei SOAP

Hallo!

ich probiere gerade etwas mit Zend_Soap.

Der SOAP Server läuft auf ein Webserver mit PHP 5.2.x, als SOAP Client verwende ich python mit SOAPpy.

Wenn ich bei einer Methode void als Rpckgabewert angeben, erhalbe ich beio SOAPpy eine Exception

HelloWorld.php
[code=php]<?php

class HelloWorld
{
    private $text = "";
    /**
     * @param  string
     * @return void
     */
    public function setText($text){
        $this->text = $text;
        return '';
    }
    /**
     * @return string
     */
    public function hello()
    {

return "Hello World!";
    }

/**
     * @return array
     */
    public function getFruits()
    {

return array('apple' , 'orange' , 'banana');
    }

}

?>[/code]

soap.php
[code=php]<?php
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application/'));
set_include_path(APPLICATION_PATH . '/../library' . PATH_SEPARATOR . get_include_path());

require_once 'Zend/Soap/Server.php';
require_once 'Zend/Soap/AutoDiscover.php';
require_once 'HelloWorld.php';

if(isset($_GET['wsdl'])){
    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('HelloWorld');
    $autodiscover->handle();
}
else{
    $soap = new Zend_Soap_Server("http://example.com/soap.php?wsdl"); // this current file here
    $soap->setClass('HelloWorld');
    $soap->handle();
}
?>[/code]

ipython
[code=python]import SOAPpy
soap = SOAPpy.WSDL.Proxy('http://example.com/soap.php?wsdl')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)

/home/stella/<ipython console> in <module>()

/var/lib/python-support/python2.5/SOAPpy/WSDL.pyc in __init__(self, wsdlsource, config, **kw)
     77         portType = binding.getPortType()
     78         for operation in portType.operations:
---> 79             callinfo = wstools.WSDLTools.callInfoFromWSDL(port, operation.name)
     80             self.methods[callinfo.methodName] = callinfo
     81

/var/lib/python-support/python2.5/SOAPpy/wstools/WSDLTools.pyc in callInfoFromWSDL(port, name)
   1551             message = messages[operation.output.message]
   1552         except KeyError:
-> 1553             if self.strict:
   1554                 raise RuntimeError(
   1555                     "Recieved message not defined in the WSDL schema: %s" %

NameError: global name 'self' is not defined[/code]

Welchen SOAP-Typ muss ich bei der Methode setText zurückgeben?

Stella

  1. Hallo,

    Welchen SOAP-Typ muss ich bei der Methode setText zurückgeben?

    Bei void natürlich gar nichts - also return einfach weglassen. Gut, ich kenne Zend_Soap jetzt nicht und weiß nicht was für ein WSDL es generiert und wie es den Rückgabewert einer Funktion genau behandelt, aber return '' gibt Dir einen Leerstring zurück, was garantiert falsch ist. Ich würd's daher mal ohne return probieren.

    Viele Grüße,
    Christian

    1. Hallo Christian

      Welchen SOAP-Typ muss ich bei der Methode setText zurückgeben?

      Bei void natürlich gar nichts - also return einfach weglassen. Gut, ich kenne Zend_Soap jetzt nicht und weiß nicht was für ein WSDL es generiert und wie es den Rückgabewert einer Funktion genau behandelt, aber return '' gibt Dir einen Leerstring zurück, was garantiert falsch ist. Ich würd's daher mal ohne return probieren.

      die return Angabe hatte ich am Anfang weggelassen, danach hatte ich "return void" probiert. Bei beiden Varianten kommt der selbe Fehler.

      Zend_Soap_Client meckert nicht rum.

      Wenn ich kein return angebe, sieht das generierte wsdl Dokument wie folgt aus

      <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://example.com/public/wsdl.php" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="HelloWorld" targetNamespace="http://example.com/public/wsdl.php">  
      <portType name="HelloWorldPort">  
      <operation name="setText">  
      <input message="tns:setTextRequest"/>  
      <output message="tns:setTextResponse"/>  
      </operation>  
      <operation name="helloWorld">  
      <input message="tns:helloWorldRequest"/>  
      <output message="tns:helloWorldResponse"/>  
      </operation>  
      <operation name="getFruits">  
      <input message="tns:getFruitsRequest"/>  
      <output message="tns:getFruitsResponse"/>  
      </operation>  
      </portType>  
      <binding name="HelloWorldBinding" type="tns:HelloWorldPort">  
      <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>  
      <operation name="setText">  
      <soap:operation soapAction="http://example.com/public/wsdl.php#setText"/>  
      <input>  
      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
      </input>  
      <output>  
      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
      </output>  
      </operation>  
      <operation name="helloWorld">  
      <soap:operation soapAction="http://example.com/public/wsdl.php#helloWorld"/>  
      <input>  
      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
      </input>  
      <output>  
      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
      </output>  
      </operation>  
      <operation name="getFruits">  
      <soap:operation soapAction="http://example.com/public/wsdl.php#getFruits"/>  
      <input>  
      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
      </input>  
      <output>  
      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>  
      </output>  
      </operation>  
      </binding>  
      <service name="HelloWorldService">  
      <port name="HelloWorldPort" binding="tns:HelloWorldBinding">  
      <soap:address location="http://example.com/public/wsdl.php"/>  
      </port>  
      </service>  
      <message name="setTextRequest">  
      <part name="text" type="xsd:string"/>  
      </message>  
      <message name="helloWorldRequest"/>  
      <message name="helloWorldResponse">  
      <part name="helloWorldReturn" type="xsd:string"/>  
      </message>  
      <message name="getFruitsRequest"/>  
      <message name="getFruitsResponse">  
      <part name="getFruitsReturn" type="soap-enc:Array"/>  
      </message>  
      </definitions>
      

      Stella

      1. Hallo,

        Wenn ich kein return angebe, sieht das generierte wsdl Dokument wie folgt aus [...]
        <output message="tns:setTextResponse"/>

        Hmm, ich bin zwar kein WSDL-Experte, aber diese Operation braucht einen Typen setTextResponse, der aber in der gesamten WSDL nicht definiert wird. Also kann die Validierung nicht funktionieren. (So interpretiere ich das zumindest.)

        Ich vermute daher (bin mir aber nicht sicher) einen Bug in Zend_Soap.

        Ich würde einfach @return boolean und dann return true; in die Funktion schreiben, dann sollte zumindest die WSDL gültig sein - den Rückgabewert musst Du ja in der aufrufenden Funktion nicht verwenden.

        Viele Grüße,
        Christian

        1. Hallo!

          Wenn ich kein return angebe, sieht das generierte wsdl Dokument wie folgt aus [...]
          <output message="tns:setTextResponse"/>

          Hmm, ich bin zwar kein WSDL-Experte, aber diese Operation braucht einen Typen setTextResponse, der aber in der gesamten WSDL nicht definiert wird. Also kann die Validierung nicht funktionieren. (So interpretiere ich das zumindest.)

          Ich vermute daher (bin mir aber nicht sicher) einen Bug in Zend_Soap.

          Ich würde einfach @return boolean und dann return true; in die Funktion schreiben, dann sollte zumindest die WSDL gültig sein - den Rückgabewert musst Du ja in der aufrufenden Funktion nicht verwenden.

          hm... ok, schön ist die Lösung zwar nicht, mir bleibt aber wohl erst einmal nichts anderes übrig

          evtl. kennt sich noch jemand anders aus und kann einen Tipp geben.

          Stella