keine Rückgabe bei SOAP
Stella L.
- programmiertechnik
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
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
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
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
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