Здравствуйте, форумчане. Я пишу веб-сервис используя стандартный класс SoapServer и файл WSDL, с описание функций и типов данных. В общем-то всё работает, но есть один маленький нюанс, который меня сильно раздражает, т.к. я не могу найти на него ответ в Интернете. При возврате массивов объектов сервер ставит тегам имя "item" вместо того имени, что я указывал в WSDL. Можно ли это как-нибудь исправить? Хотелось бы так: HTML: <Services> <Service> <Name>PAYMENT_CASH</Name> <Enabled>true</Enabled> </Services> <Service> <Name>PAYMENT_CARD</Name> <Enabled>true</Enabled> </Services> </Services> А получается так: HTML: <Services> <item> <Name>PAYMENT_CASH</Name> <Enabled>true</Enabled> </item> <item> <Name>PAYMENT_CARD</Name> <Enabled>true</Enabled> </item> </Services> Вот часть WSDL с описанием типов: HTML: <xsd:complexType name="Services"> <xsd:complexContent> <xsd:restriction base="SOAP-ENC:Array"> <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:Service[]" /> </xsd:restriction> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="Service"> <xsd:all> <xsd:element name="Name" type="xsd:string" /> <xsd:element name="Enabled" type="xsd:boolean" /> </xsd:all> </xsd:complexType> PHP: PHP: function getServices() { $Response = new stdClass(); ... $Response->Services = []; $Services = ServiceManager->getAll(); foreach ($Services as $Service) { // $Service - экземпляр класса Service, подробно описывающий предоставляемую услугу. $Response->Services[] = (object) ['Name' => $Service->getName(), 'Enabled' => $Service->isEnabled()]; } ... return $Response; }
Спасибо за столь развёрнутый и обоснованный ответ...)) Но хотелось бы больше конкретики. И ещё. В документации по конструктору класса SoapServer ( https://php.ru/manual/soapserver.soapserver.html ) очень мало информации по использованию опции features и константам SOAP_WAIT_ONE_WAY_CALLS, SOAP_SINGLE_ELEMENT_ARRAYS и SOAP_USE_XSI_ARRAY_TYPE. Использование SOAP_SINGLE_ELEMENT_ARRAYS в клиенте SoapClient понятно, он позволяет вернуть элемент, содержащий массив именно как массив, даже если в нём самом всего один элемент массива: В клиенте БЕЗ опции SOAP_SINGLE_ELEMENT_ARRAYS: Код (Text): object(stdClass)#1 (1) { [ 'Services'] => object(stdClass)#2 (1) { [ 'Service'] => object(stdClass)#3 (2) { [ 'Name'] => string(12) "PAYMENT_CARD" ['Enabled'] => boolean true } } } В клиенте С опцией SOAP_SINGLE_ELEMENT_ARRAYS: Код (Text): object(stdClass)#1 (1) { [ 'Services'] => object(stdClass)#2 (1) { [ 'Service'] => array(1) { [0]=> object(stdClass)#3 (2) { [ 'Name'] => string(12) "PAYMENT_CARD" ['Enabled'] => boolean true } } } } По поводу влияния остальных констант я не знаю, в особенности их влияния на SoapServer. Поясните пожалуйста, кто в курсе.
Ладно. Видимо вопрос для многих нерешённый или совсем ненужный. Попробую сам разобраться. Может кому тоже пригодится. Вот что нашёл ( https://stackoverflow.com/questions...difference-between-soapserver-features-option ): SOAP_WAIT_ONE_WAY_CALLS Without this, SOAP will not wait for a response on one way calls. It will just continue on and assume that all is well in the world. A one way call is anything that does not have a response in the WSDL. SOAP_SINGLE_ELEMENT_ARRAYS Your SOAP call may return a single value, or it may return an array of values. However, if you enable this flag, then it will force that single value to be an array with just the single value. You'll know what your data looks like without having to check it. SOAP_USE_XSI_ARRAY_TYPE This sets the deserialization type. If an error like this comes up "No deserializer defined for array type {http://www.w3.org/2001/XMLSchema}", then look to enable this feature.