• 4402
  • 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
846

Загрузка...
Loading...

Комментарии

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

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

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

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

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

Прогноз эксперта: в Казахстане будут жить 5 миллионов китайцев

Прогноз эксперта: в Казахстане будут жить 5 миллионов китайцев

В ближайшие годы в Центральной Азии будут проживать восемь миллионов китайцев, считает заведующий отделением востоковедения национального исследовательского университета высшей школы экономики.
kurmanovainur
23 июня 2017 / 11:23
  • 39508
  • 19
Они сделали это! Kaspi Bank презентовал свое мобильное приложение

Они сделали это! Kaspi Bank презентовал свое мобильное приложение

Изучив ошибки предшественников и собрав воедино новейшие идеи онлайн-банкинга, Kaspi Bank наконец выпустил... свое мобильное приложение!
niyazov
20 июня 2017 / 15:05
  • 8580
  • 5
Кайрат Келимбетов об азербайджанской инвестиции: «Вернется и «тело», и проценты»!

Кайрат Келимбетов об азербайджанской инвестиции: «Вернется и «тело», и проценты»!

Мы записали уникальное интервью с Кайратом Келимбетовым. Предлагаю вам посмотреть первую часть, где мы постарались по возможности поставить все точки на «I» именно по Азербайджанскому вопросу.
Zhumanova
19 июня 2017 / 12:00
  • 6195
  • 7
Почему мы должны быть благодарны журналисту Джеймсу Палмеру за критику ЭКСПО

Почему мы должны быть благодарны журналисту Джеймсу Палмеру за критику ЭКСПО

Как одним критичным постом зарубежному журналисту Джеймсу Палмеру удалось вскрыть сразу несколько гнойников казахстанского общества.
anotherblogger
21 июня 2017 / 0:39
  • 6476
  • 63
В каких случаях у вас могут изъять удостоверение личности?

В каких случаях у вас могут изъять удостоверение личности?

Недавно один знакомый задал вопрос: «Я сейчас выступаю как свидетель по одному делу. У меня забрали удостоверение личности (УЛ) в РУВД и не вернули обратно. Так можно?». Я сразу задалась вопросом...
asselsabekova
21 июня 2017 / 10:17
  • 2893
  • 10
В Казахстане заблокировали сайт, раскритиковавший EXPO в «захолустной» Астане

В Казахстане заблокировали сайт, раскритиковавший EXPO в «захолустной» Астане

Все помнят Медузу и ЖЖ. Теперь в этот "особенный" список попал сайт Foreign policy. Предполагается, что причиной блокировки стала нелицеприятная заметка Джеймса Палмера об EXPO в Астане.
Seattle
19 июня 2017 / 15:40
Инструкции по сопроводительному письму и собеседованию, которые подойдут всем

Инструкции по сопроводительному письму и собеседованию, которые подойдут всем

Наткнулась на статью Ассоциации юристов Новой Зеландии, в которой они дают советы выпускникам юрфака по поиску работы. Статья меня поразила, поскольку там описано все до мелочей, а их советы подойдут абсолютно всем.
asselsabekova
20 июня 2017 / 16:10
  • 2565
  • 6
На Иссык-Куль через Юг. Не бойтесь ехать в Киргизию своим ходом!

На Иссык-Куль через Юг. Не бойтесь ехать в Киргизию своим ходом!

Очень живописная и бюджетная поездка вдоль всего берега по Иссык-Кулю! Мы, две обаятельные девушки, поехали вдвоем, подготовленные к совершенно автономной жизни в палатке, и ни разу ничего не...
yelenasergiyenko
22 июня 2017 / 13:20
  • 2433
  • 20
Это «колхозное сооружение» вредит имиджу города. Я, как алматинка, против!

Это «колхозное сооружение» вредит имиджу города. Я, как алматинка, против!

Почему эту трубу не проложили под землей? Она обезображивает улицу, как дикий багровый шрам от раны, зашитой равнодушным, криворуким и ленивым хирургом, обезображивает лицо.
ValentinaVladimirska
23 июня 2017 / 12:10
  • 2089
  • 31