• 4502
  • 70
  • 4
Нравится блог?
Подписывайтесь!

SOAP сервер на Zend Framework с использованием Zend_Soap_AutoDiscover для работы с клиентом написаным на .NET

При работе над одним порталом у нас возникла задача, по обмену данными между порталом и несколькими другими программами написанными на .NET. Разработчики этих программ настаивали сделать взаимодействие при помощи SOAP, мы согласились.

В этой статье хотелось бы раскрыть проблемы возникшие при разработке SOAP сервера на Zend Framework с использованием Zend_Soap_AutoDiscover.

Так как портал был полностью реализован на Zend Framework мы и решили реализовать SOAP сервер на нем. Так же мы решили использовать AutoDiscover что бы не писать wsdl файл в ручную, так как планировалось что в наш сервер будет добавляться различный функционал в будущем. И не хотелось тратить время на описание этих функций в wsdl файле. Заглянув в ман мы нашли код нужный для создания SOAP сервера.

  1. if(isset($_GET['wsdl'])) {
  2. $autodiscover = new Zend_Soap_AutoDiscover();
  3. $autodiscover->setClass('ExcampleService');
  4. $autodiscover->handle();
  5. } else {
  6. // pointing to the current file here
  7. $soap = new Zend_Soap_Server("http://example.com/soap.php?wsdl");
  8. $soap->setClass('ExcampleService');
  9. $soap->handle();
  10. }

Как же все просто подумали мы, но .NET отказался работать с нашим сервером. Мы стали искать проблемы почему не работает наш сервер с .NET программами, когда клиент на PHP успешно обменивался данными с ним.

Проблема первая.

Как мы знаем PHP не типизированный язык, когда .NET типизированный и это первая проблема. Потому что при генерации wsdl AutoDiscover не может определить типы возвращаемых данных. Для решения этой проблемы нужно указывать тип возвращаемых данных в описании функций.

Пример описания:

  1. class ExcampleService {
  2. /**
  3. * Return true if record active, else if record inactive
  4. *
  5. * @param integer $recordId
  6. * @return boolean
  7. */
  8. public function isActiveRecord($recordId) {
  9. $recordsTable = new Model_Records();
  10. return $recordsTable->isActiveRecord($recordId);
  11. }
  12. }

При просмотре wsdl выяснилось что типы простых данных указываются, но если возвращается массив то тип его элементов не указывается. Воспользовавшись поисковиками мы нашли решение. Возвращать не массив а объект с массивом других объектов. Типы всех свойств должны быть указаны в описании этих объектов.

Пример описания классов возвращаемых объектов:

 
  1. class SRecord {
  2. /** @var int */
  3. public $id;
  4. /** @var string */
  5. public $text;
  6. }
  7. class SRecordsArray {
  8. /** @var SRecord[] */
  9. public $records;
  10. }

И код самого класса ExcampleService:

  1. class ExcampleService {
  2. /**
  3. * Return true if record active, else if record inactive
  4. *
  5. * @param integer $recordId
  6. * @return boolean
  7. */
  8. public function isActiveRecord($recordId) {
  9. $recordsTable = new Model_Records();
  10. return $recordsTable->isActiveRecord($recordId);
  11. }
  12. /**
  13. * Return list of records
  14. *
  15. * @return SRecordsArray
  16. */
  17. public function getList() {
  18. $recordsTable = new Model_Records();
  19. $records = $recordsTable -> getList();
  20. $result = array();
  21. foreach ($records as $record) {
  22. $oSrecord = new SRecord();
  23. $oSrecord->id = $record->id;
  24. $oSrecord->text = $record->text;
  25. $result[] = $oSrecord;
  26. }
  27. $oSrecordsArray = new SRecordsArray();
  28. $oSrecordsArray->records = $result;
  29. return $oSrecordsArray;
  30. }
  31. }
 

Сохраняем изменения запускаем программу .NET и видим что она снова отказывается работать.

Проблема вторая.

Проблема в том что .NET поддерживает только один стандарт SOAP WS-I а AutoDiscover по умолчанию использует стандарт XSD поэтому нам нужно привести wsdl к стандарту WS-I. Для этого нам нужно доработать первоначальный код следующим образом.

 
  1. if(isset($_GET['wsdl'])) {
  2. $autodiscover = new Zend_Soap_AutoDiscover('Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence');
  3. $autodiscover->setBindingStyle(array('style'=>'document'));
  4. $autodiscover->setOperationBodyStyle(array('use' => 'literal'));
  5. $autodiscover->setClass('ExcampleService');
  6. $autodiscover->handle();
  7. } else {
  8. // pointing to the current file here
  9. $soap = new Zend_Soap_Server("http://example.com/soap.php?wsdl");
  10. $soap->setClass('ExcampleService');
  11. $soap->handle();
  12. }

Сохраняем изменения, обновляем сервер, запускаем программу на .NET и что мы видим, программа выполняет все методы сервера но получает от сервера всегда только null.

Проблема третья.

Последняя проблема связанна с получением и передачей данных. Для решения этой проблемы мы написали специальный класс который трансформирует входящие и исходящие данные.

Исходный код класса:

  1. class Service_Soap
  2. {
  3. protected $_service;
  4. public function __construct()
  5. {
  6. $this->_service = new ExcampleService();
  7. }
  8. public function __call($name, $arguments)
  9. {
  10. $params = array();
  11. if(count($arguments) > 0){
  12. foreach($arguments[0] as $property=>$value){
  13. $params[$property] = $value;
  14. }
  15. }
  16. $result = call_user_func_array(array($this->_service, $name), $params);
  17. return array("{$name}Result" => $result);
  18. }
  19. }
 

И доработали код создания сервера

 
  1. if(isset($_GET['wsdl'])) {
  2. $autodiscover = new Zend_Soap_AutoDiscover('Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence');
  3. $autodiscover->setBindingStyle(array('style'=>'document'));
  4. $autodiscover->setOperationBodyStyle(array('use' => 'literal'));
  5. $autodiscover->setClass('ExcampleService');
  6. $autodiscover->handle();
  7. } else {
  8. // pointing to the current file here
  9. $soap = new Zend_Soap_Server("http://example.com/soap.php?wsdl");
  10. //$soap->setClass('ExcampleService');
  11. $modelSoap = new Service_Soap();
  12. $soap->setObject($modelSoap);
  13. $soap->handle();
  14. }
 

После сохранения программа на .NET заработала и портал стал обмениваться данными с ней.

Надеюсь что этот пост поможет кому то при разработке SOAP сервера. И он уже быстро справится с проблемами описанными в статье, нам решение этих проблем заняло достаточно времени.

Спасибо всем за внимание и удачи вам!

alexboo
26 августа 2012, 11:41
872

Loading...

Комментарии

Предлагаю виртуально посетить замок Амбрас turdnevnikzima.ru и ещё остров Ата bookokeania.ru и Ряшков turistbook.ru информация о двери turistleto.ru

Оставьте свой комментарий

Спасибо за открытие блога в Yvision.kz! Чтобы убедиться в отсутствии спама, все комментарии новых пользователей проходят премодерацию. Соблюдение правил нашей блог-платформы ускорит ваш переход в категорию надежных пользователей, не нуждающихся в премодерации. Обязательно прочтите наши правила по указанной ссылке: Правила

Также можно нажать Ctrl+Enter

Популярные посты

Бесспорные доказательства – путь к упрощенному судопроизводству

Бесспорные доказательства – путь к упрощенному судопроизводству

В Казахстане введен институт упрощенного (письменного) судопроизводства, который позволяет повысить доступность правосудия и сократить сроки рассмотрения дел.
mark_iceberg
20 нояб. 2017 / 15:49
  • 15960
  • 3
Новшества на орбите уголовного правосудия

Новшества на орбите уголовного правосудия

Недавно я приняла участие в международной конференции по модернизации уголовного процесса, прошедшей в Бурабае. В чем значимость данных реформ для обычного казахстанца?
mirabeisenova
20 нояб. 2017 / 16:22
  • 12738
  • 3
О «топ-30», «топ-50» и прочих понтах можно пока забыть

О «топ-30», «топ-50» и прочих понтах можно пока забыть

В объективности выводов швейцарского банка Credit Suisse усомниться трудно – его экономические рейтинги относятся к самым авторитетным и их явно трудно упрекнуть в предвзятости
openqazaqstan
18 нояб. 2017 / 17:21
  • 8148
  • 92
Опровержение на статью «Самый большой мошенник в стране – Казахтелеком»

Опровержение на статью «Самый большой мошенник в стране – Казахтелеком»

По требованию компании АО «Казахтелеком», Блог-платформы YourVision» сообщает своим пользователям, что сведения, изложенные в статье, являются непроверенными.
yvision
вчера / 15:29
Атамбаев под занавес президентства сделал всё, чтобы сжечь мосты

Атамбаев под занавес президентства сделал всё, чтобы сжечь мосты

На своей итоговой пресс-конференции в понедельник уходящий кыргызский президент говорил не об итогах своей деятельности, а о «плохом» Казахстане.
openqazaqstan
21 нояб. 2017 / 18:36
«Смех сквозь слезы», или 7 причин не любить Алматы

«Смех сквозь слезы», или 7 причин не любить Алматы

Жизнь в Алматы не всегда сладкая, как сахарная вата и мультики субботним утром. В этой ироничной статье автор блога «Almaty — My First Love» расскажет о семи причинах не любить Алматы.
AlmatyMyLove
20 нояб. 2017 / 13:12
  • 3163
  • 71
В Кызылорде нет Детского дома: мы построили 8 коттеджей для детей

В Кызылорде нет Детского дома: мы построили 8 коттеджей для детей

Тут живут будущие повара, актрисы, журналисты, боксеры, баскетболисты, певцы, поэты и многие другие талантливые дети!
socium_kzo
22 нояб. 2017 / 14:49
  • 2578
  • 0
«Развитие Казахстана самими гражданами»: миф или реальность?

«Развитие Казахстана самими гражданами»: миф или реальность?

Проблем в обществе много: даже больше, чем догадывается среднестатистический казахстанец. И тут я хочу описать несколько, с моей точки зрения, проблем нашего общества.
Advokot
18 нояб. 2017 / 23:27
«Полет ради полета»: знакомство с калужской авиацией изнутри

«Полет ради полета»: знакомство с калужской авиацией изнутри

В прошлом году на мероприятии "Слет Авиатора" я выиграла подарок - экскурсию на командно-диспетчерский пункт (КДП). Но тогда я даже не ожидала, что эта экскурсия выльется в такое интересное...
Aleksandra747
20 нояб. 2017 / 9:00
  • 1771
  • 6