Использование опции class SoapClient класса PHP с WSDL, содержащей элемент и complexType с тем же именем
Я столкнулся с несколькими различными файлами WSDL, которые содержат элемент и complexType с тем же именем. Например, http://soap.search.msn.com/webservices.asmx?wsdl имеет два объекта с именем "SearchResponse":
В этом случае я не могу понять, как правильно сопоставить эти объекты с PHP-классами с помощью параметра SoapClient() "classmaps".
В руководстве PHP сказано следующее:
Опция classmap может использоваться для отображения некоторые типы WSDL для классов PHP. Эта параметр должен быть массивом с WSDL типы как ключи и имена классов PHP как значения.
К сожалению, поскольку существует два типа WSDL с одним и тем же ключом ( "SearchResponse" ), я не могу понять, как различать два объекта SearchResponse и назначать их соответствующим классам PHP.
Например, вот соответствующий фрагмент примера WSDL:
<xsd:complexType name="SearchResponse">
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="Responses" type="tns:ArrayOfSourceResponseResponses"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="SearchResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="Response" type="tns:SearchResponse"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
И вот PHP, который, очевидно, будет не работать, поскольку ключи classmaps одинаковы:
<?php $server = new SoapClient("http://soap.search.msn.com/webservices.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MySearchResponseElement', 'SearchResponse' => 'MySearchResponseComplexType'))); ?>
В поисках решения я нашел, что Java Web Services обрабатывает это, позволяя вам указать собственный суффикс для объектов "Элемент" или "Комплексный тип".
http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp149350
Итак, прямо сейчас я чувствую, что с PHP SoapClient просто нет способа сделать это, но мне любопытно, сможет ли кто-нибудь предложить какие-либо советы. FWIW, я не могу редактировать удаленный WDSL.
Любые идеи???
Ответы
Ответ 1
Это не в моей голове, но я думаю, что вы могли бы отображать типы SearchResponse для MY_SearchResponse и попытаться абстрагировать разницу между ними. Это kludgy, но что-то вроде этого возможно?
<?php
//Assuming SearchResponse<complexType> contains SearchReponse<element> which contains and Array of SourceResponses
//You could try abstracting the nested Hierarchy like so:
class MY_SearchResponse
{
protected $Responses;
protected $Response;
/**
* This should return the nested SearchReponse<element> as a MY_SearchRepsonse or NULL
**/
public function get_search_response()
{
if($this->Response && isset($this->Response))
{
return $this->Response; //This should also be a MY_SearchResponse
}
return NULL;
}
/**
* This should return an array of SourceList Responses or NULL
**/
public function get_source_responses()
{
//If this is an instance of the top SearchResponse<complexType>, try to get the SearchResponse<element> and it source responses
if($this->get_search_response() && isset($this->get_search_response()->get_source_responses()))
{
return $this->get_search_response()->get_source_responses();
}
//We are already the nested SearchReponse<element> just go directly at the Responses
elseif($this->Responses && is_array($this->Responses)
{
return $this->Responses;
}
return NULL;
}
}
class MY_SourceResponse
{
//whatever properties SourceResponses have
}
$client = new SoapClient("http:/theurl.asmx?wsdl", array('classmap' => array('SearchResponse' => 'MY_SearchResponse', 'SourceResponse' => 'MY_SourceResponse')));