Zend Framework 2 SOAP自动发现和复杂类型

编程入门 行业动态 更新时间:2024-10-25 14:33:19
本文介绍了Zend Framework 2 SOAP自动发现和复杂类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在准备SOAP服务器,并使用以下代码生成WSDL:

I'm preparing the SOAP server and generating my WSDL using the follow code:

//(... Controller action code ...) if (key_exists('wsdl', $params)) { $autodiscover = new AutoDiscover(); $autodiscover->setClass('WebServiceClass') ->setUri('server/webserver/uri'); $autodiscover->handle(); } else { $server = new Server(null); $server->setUri($ws_url); $server->setObject($this->getServiceLocator()->get('MyController\Service\WebServiceClass')); $server->handle(); } //(... Controller action code ...)

但是在我的WebService方法之一中,我有一个Array类型的参数,其中每个元素的类型均为"MyOtherClass",如下所示:

But in one of my WebService method I have a parameter of type Array in which each element is of type "MyOtherClass", like follows:

/** * Add list of MyOtherClass items * * @param MyOtherClass[] $items * * @return bool */ function add($items) { // Function code here }

当我尝试生成WSDL时,出现以下错误:

When I try to generate the WSDL I get the follow error:

PHP Warning: DOMDocument::loadXML(): Empty string supplied as input in /<zend framweork path>/Server/vendor/zendframework/zendframework/library/Zend/Soap/Server.php on line 734

还是这个例外:

Cannot add a complex type MyOtherClass[] that is not an object or where class could not be found in "DefaultComplexType" strategy.

当我将代码添加到我的代码中时:

When I added to my code something like this:

//(...) if (key_exists('wsdl', $params)) { $autodiscover = new AutoDiscover(); $autodiscover->setClass('WebServiceClass'); $autodiscover->setUri($ws_url); $complex_type_strategy = new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeComplex(); $complex_type_strategy->addComplexType('MyOtherClass'); $autodiscover->setComplexTypeStrategy($complex_type_strategy); $autodiscover->handle(); } else { //(...)

我收到以下错误消息:

Fatal error: Call to a member function getTypes() on a non-object in /<project dir>/vendor/zendframework/zendframework/library/Zend/Soap/Wsdl/ComplexTypeStrategy/AbstractComplexTypeStrategy.php on line 54

在简历中,问题是:如何知道用作参数的新Custom Type的WSDL?

In resume, the question is: how can I make aware the WSDL of the new Custom Type used as parameter?

谢谢

推荐答案

我做了类似的事情,这是示例代码:

I did something similar and this is a sample code:

/* code.... */ if (array_key_exists('wsdl', $this->request->getQuery()) || array_key_exists('WSDL', $this->request->getQuery())) { $auto = new \Zend\Soap\AutoDiscover(new \Zend\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence()); $auto->setClass($controllerClassName); $auto->setUri(sprintf('%s://%s%s', \Application\Bootstrap::getServiceManager()->get('config')[APPLICATION_ENV]['webServer']['protocol'], $this->request->getUri()->getHost() , $this->request->getUri()->getPath())); $auto->setServiceName(ucfirst($this->request->getModuleName()) . ucfirst($this->request->getControllerName())); header('Content-type: application/xml'); echo $auto->toXML(); } elseif (count($this->request->getQuery()) == 0) { $this->preDispatch(); $wsdl = sprintf('%s://%s%s?wsdl', \Application\Bootstrap::getServiceManager()->get('config')[APPLICATION_ENV]['webServer']['protocol'], $this->request->getUri()->getHost() , $this->request->getUri()->getPath()); $soapServer = new \Zend\Soap\Server($wsdl); $soapServer->setClass($controllerClassName); $soapServer->handle(); } /* code */

这是自动发现将基于注释生成wsdl的一个类的功能签名的片段:

This is a fragment of the function signature of one of the classes that the autodiscover will generate the wsdl based on the annotations:

/** * Allows to search for a patient based on the patient id * * @param int $id * @return \ViewModels\PatientViewModel * @throws \Application\Exception */ protected function searchPatientById($id) { /* .... code */

这是类\ ViewModels \ PatientViewModel和\ ViewModel \ DiagnosisViewModel 在此注意我如何使用注释声明字段包含复杂类型的数组,然后如何将其转换为wsdl上的ArrayOfDiagnosisViewModel

This is the class \ViewModels\PatientViewModel and \ViewModel\DiagnosisViewModel Notice here how i used the annotations to declare that a field conatins an array of a complextype, and then how that is translated as ArrayOfDiagnosisViewModel on the wsdl

namespace ViewModels; class PatientViewModel { /** * @var int * */ public $id; /** * @var string * */ public $firstname; /** * @var string * */ public $lastname; /** *** @var \ViewModels\DiagnosisViewModel[]** * */ public $diagnosis; } class DiagnosisViewModel { /** * @var int */ public $id; /** * @var string */ public $name; }

这是生成的WSDL

<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="schemas.xmlsoap/wsdl/" xmlns:wsdl="schemas.xmlsoap/wsdl/" xmlns:tns="soa.local/soap/Sample/Main" xmlns:soap="schemas.xmlsoap/wsdl/soap/" xmlns:xsd="www.w3/2001/XMLSchema" xmlns:soap-enc="schemas.xmlsoap/soap/encoding/" xmlns:soap12="schemas.xmlsoap/wsdl/soap12/" name="SampleMain" targetNamespace="soa.local/soap/Sample/Main"> <types> <xsd:schema targetNamespace="soa.local/soap/Sample/Main"> <xsd:complexType name="DiagnosisViewModel"> <xsd:all> <xsd:element name="id" type="xsd:int" nillable="true"/> <xsd:element name="name" type="xsd:string" nillable="true"/> </xsd:all> </xsd:complexType> **<xsd:complexType name="ArrayOfDiagnosisViewModel"> <xsd:sequence> <xsd:element name="item" type="tns:DiagnosisViewModel" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType>** <xsd:complexType name="PatientViewModel"> <xsd:all> <xsd:element name="id" type="xsd:int" nillable="true"/> <xsd:element name="firstname" type="xsd:string" nillable="true"/> <xsd:element name="lastname" type="xsd:string" nillable="true"/> <xsd:element name="diagnosis" type="tns:ArrayOfDiagnosisViewModel" nillable="true"/> </xsd:all> </xsd:complexType> </xsd:schema> </types> <portType name="SampleMainPort"> <operation name="searchPatientById"> <documentation>Allows to search for a patient based on the patient id</documentation> <input message="tns:searchPatientByIdIn"/> <output message="tns:searchPatientByIdOut"/> </operation> </portType> <binding name="SampleMainBinding" type="tns:SampleMainPort"> <soap:binding style="rpc" transport="schemas.xmlsoap/soap/http"/> <operation name="searchPatientById"> <soap:operation soapAction="soa.local/soap/Sample/Main#searchPatientById"/> <input> <soap:body use="encoded" encodingStyle="schemas.xmlsoap/soap/encoding/" namespace="soa.local/soap/Sample/Main"/> </input> <output> <soap:body use="encoded" encodingStyle="schemas.xmlsoap/soap/encoding/" namespace="soa.local/soap/Sample/Main"/> </output> </operation> </binding> <service name="SampleMainService"> <port name="SampleMainPort" binding="tns:SampleMainBinding"> <soap:address location="soa.local/soap/Sample/Main"/> </port> </service> <message name="searchPatientByIdIn"> <part name="id" type="xsd:int"/> </message> <message name="searchPatientByIdOut"> <part name="return" type="tns:PatientViewModel"/> </message> </definitions>

请注意,仅通过更改策略和正确的DOCBLOCK注释,您就可以实现.

NOTICE THAT JUST BY CHANGING THE STRATEGY AND THE RIGHT DOCBLOCKS ANNOTATIONS YOU CAN ACHIEVE THAT.

希望此片段可以帮助您找到解决方案.

HOPE THIS SNIPPETS CAN HELP YOU TO FIND A SOLUTION.

更多推荐

Zend Framework 2 SOAP自动发现和复杂类型

本文发布于:2023-11-16 16:00:16,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1605742.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类型   发现   Zend   Framework   SOAP

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!