За последние 24 часа нас посетили 85205 программистов и 4733 робота. Сейчас ищут 1793 программиста ...

SOAP веб-сервис на PHP

Тема в разделе "PHP для новичков", создана пользователем cheater, 4 май 2010.

  1. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Мне надо связать SilverLigth и MySQL.
    Для начала я написал простенький SOAP сервис на PHP, используя библиотеку NuSOAP (исключительно для теста выдрал из мануала):
    PHP:
    1. <?php
    2. // Подключаем код NuSOAP
    3. require_once('nusoap.php');
    4. // Создаем экщемпляр сервиса
    5. $server = new soap_server();
    6. // Инициализируем поддержку WSDL
    7. $server->configureWSDL('hellowsdl2', 'urn:hellowsdl2');
    8. // Устанавливаем пространство имен с префиксом tns для WSDL-схемы
    9. $server->wsdl->schemaTargetNamespace = 'urn:hellowsdl';
    10.  
    11. // Регистрируем предоставляемый метод
    12. $server->register('hello',                    // название метода
    13.     array('person'=>"xsd:string"),          // входные параметры
    14.     array('return'=>"xsd:string"),    // выходные параметры
    15.     'urn:hellowsdl2',                         // пространство имен
    16.     'urn:hellowsdl2#hello',                   // soapaction
    17.     'rpc',                                    // стиль
    18.     'literal',                                // использование
    19.     'Greet a person entering the sweepstakes'        // документация
    20. );
    21.  
    22. // Определяем метод как функцию PHP
    23. function hello($person) {
    24.     return "Good";
    25. }
    26.  
    27. // Используем HTTP-запрос чтобы вызвать сервис
    28. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
    29. $server->service($HTTP_RAW_POST_DATA);
    30. ?>
    Идёт запрос от клиента SilverLight:
    HTML:
    1. <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><ProcessSimpleType xmlns="http://sanity-free.org/services"><name xmlns="">Serg</name></ProcessSimpleType></s:Body></s:Envelope>
    Приходит ответ от сервиса:
    HTML:
    1. <?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    2.  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    3.  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    4.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    5.  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
    6. <SOAP-ENV:Body><SOAP-ENV:Fault><faultcode xsi:type="xsd:string">SOAP-ENV:Server</faultcode><faultactor xsi:type="xsd:string"></faultactor><faultstring xsi:type="xsd:string">unable to serialize result</faultstring><detail xsi:type="xsd:string"></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
    Как устранит ошибку unable to serialize result ?
    Если есть более простые варианты для написания SOAP сервиса, то буду не против от ссылки на хороший мануал, желательно на русском, но и буржуйский сойдёт.
     
  2. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
  3. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    1. А есть люда, которые удачно из C# вызывали методы классов, написанных в стиле zend?
    2. У меня есть zend studio 7, но там в экспорте нету варианта сгенерить WSDL файл из PHP класса, хотя в 6.2 было. Может генерить WSDL с помощью NuSOAP или могут возникнуть проблемы?
    3. Вот phpinfo сервера - не будет ли у меня проблем с zend server?

    ПС:
    можно самый маленький веб-сервис, чтобы потестить возможности адекватной работы хостера? А то раньше пробовал примеры приведённые на сайте zend по автообноружению сервисов = автогенерации WSDL, но ничего толкового не получилось - VS даже не находила WSDL, не говоря уже про нахождение методов в нём. Если нету времени, то можете пропустить эту просьбу, т.к. не критично, но может сэкономить время в поиске ошибок, ведь если у человека работает тот или иной пример, то он должен работать и у меня.
     
  4. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    Если внимательно прочтете ссылку на документацию, то увидите там класс, который позволяет сгенерировать WSDL по написанному вами сервису и сохранить результат в файл.

    Zend Server как бы тут не причем. Что касается SOAP то работать должен, поскольку соответствующее расширение имеется.
     
  5. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    1. Ну я был написал, что пробовал по их классу WSDL сгенерировать, но как-то не ахти получилось.
    2. Если открыть потом файл .php, то должно ли появится что-то похожее на это с описаниями всех методов(чтобы узнать, что нигде нету ошибок)?
    3. Если вас не затруднит, то можно сорс какого-нибудь примера уже полного и 100% работающего, чтобы по аналогии сделать своё, а то видно я что-то из документации недопонял (у них там нету ни одного толкового экземпла - один отрывки).

    Люди, ну неужто никто не может мне помочь? Попробовал сорсы без zend'а, а чисто с расширением SOAP, где сервер и клиент на PHP и используется уже готовый WSDL файл, но опять фэйл - снифер только заголовки увидел(клиент ни одного сообшения не отправил :cry:). Сорсы взяты отсюда. Даже не знаю что делать. Плиз, помогите! Очень прошу, а то я уже и так много дней бьюсь об эту каменную стену. Нужен хотя б один пример, чтобы залить на http://alone.iam.by/SOAP и проверить "общение" с С#, а потом на основании этого примера сделать свои сервисы.
     
  6. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    И что именно не устроило?

    Не понял в чем вопрос? какой .php файл? Что и где должно появится?
    WSDL генерируется примерно такой
    http://simpliest.co.cc/sample/soapserver/wsdl.xml

    Меня затруднит. Я не даю готовых решений, тем более когда их просят.

    Я подскажу.
    Делать надо это http://phpfaq.ru/debug
     
  7. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Не получилось получить wsdl файл.
    Просто в NuSOAP как и в .NET (на лету) файл справки с полным описание всех методов и классов + ссылка на генерацию WSDL (опять же на лету - нигде не сохраняется). В вашем примере по-моим представлениям WSDL файлом должен выступать: http://simpliest.co.cc/sample/soapserver/index.php?wsdl
    Zend Framework генерит wsdl файл и пытается его записать в ту же папку - тогда это может стать ответом? Я не могу поставить права на запись файлов - можно ли это обойти?
    Я не прошу решить мою проблему - я лишь прошу дать мне любой - абсолютно любой 100% работающий SOAP веб-сервис - нужен толковый пример. Если нету, то не стоит напрягаться.
    Логи апачи ничего не дают, т.к. ответ приходит с исключением, если юзать NuSOAP, а с zend framework мне просто не понятно что да к чему.

    ПС:
    неужто на этом форуме никто не может направить меня в нужное русло? :(
     
  8. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    Посмотрите методы, которые есть у Zend_Soap_AutoDiscover

    Он и может им выступать. Это результат работы Zend_Soap_AutoDiscover, который параллельно еще пишется в wsdl.xml
    В чем сложность?

    Там есть два режима - записать в файл и просто отдать как обычную страницу.

    У меня стойкое ощущение, что Вы просто не читали мануал и не смотрели соответствующее API. И это корень всех проблем.

    Мануал, мануал, мануал, мануал.... черт возьми!
    Там есть минимальный 100% работающий пример кода. Запускается за 5 минут.

    Причем тут логи апача? Вы даже не удосужились прочитать ссылку что я дал.
    Речь идет об отладке алгоритмов
    Я не вижу смысла помогать человеку, который не желает прилагать усилий.

    Если не хотите разбираться, то у Вас есть два варианта
    - Идете ищете фрилансера, который это сделает за деньги.
    - Можете обратится к местным "профессионалам" - Kreker, [vs], antonn, Апельсин.
    Они, правда, в этом вообще не разбираются, но чудеса бывают :D вдруг они смогут вам помочь :)
     
  9. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Нашёл решение тут
    Юзаю NuSOAP.
    Возможно дело в кодировке - буду искать.
    Simpliest,
    обещаю в будущем внимательнее изучить мануал - может я и упустил режимы работы и прочее, но это было ненарошно - очень невнимательный по жизни, а когда не получается что-то, то вообще торможу. Спасибо, что хоть чем-то помогали, а не игнорили как все остальные на этом форуме.
    ПС:
    к zend framework обязательно вернусь, т.к. мне кажется более перспективным решением, чем NuSOAP.

    Update:
    действительно всё дело в кодировке.
    Надо было добавить одну лишь строчку:
    PHP:
    1. $server->soap_defencoding = 'utf-8';
    А вот и весь код
    PHP:
    1. <?php
    2. // Подключаем код NuSOAP
    3. require_once('nusoap.php');
    4. // Создаем экщемпляр сервиса
    5. $server = new soap_server();
    6. // Инициализируем поддержку WSDL
    7. $server->configureWSDL('hellowsdl2', 'urn:hellowsdl2');
    8. // Устанавливаем пространство имен с префиксом tns для WSDL-схемы
    9. $server->wsdl->schemaTargetNamespace = 'urn:hellowsdl';
    10.  $server->soap_defencoding = 'utf-8';
    11. // Регистрируем предоставляемый метод
    12. $server->register('hello',                    // название метода
    13.     array('person'=>'xsd:string'),          // входные параметры
    14.     array('return'=>'xsd:string'),    // выходные параметры
    15.     'urn:hellowsdl2',                         // пространство имен
    16.     'urn:hellowsdl2#hello',                   // soapaction
    17.     'rpc',                                    // стиль
    18.     'literal',                                // использование
    19.     'Greet a person entering the sweepstakes'        // документация
    20. );
    21.  
    22. // Определяем метод как функцию PHP
    23. function hello($person) {
    24.     return "Good";
    25. }
    26.  
    27. // Используем HTTP-запрос чтобы вызвать сервис
    28. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
    29. $server->service($HTTP_RAW_POST_DATA);
    30. ?>
    Надеюсь, что мне потом кто-нибудь расскажет как это же сделать на zend framework ^^.
     
  10. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Столкнулся с проблемой. Мне надо при запросе отправить в качестве ответа всю таблицу MySQL. Т.е. типа массива структур. Пробовал реализовывать по-разному, но то VS ругается, что используется encoded стиль, то ответ приходит не такой, как я ожидал. Может кто-нибудь подсказать, желательно с наглядным примером, как можно реализовать такое на PHP (в виду SOAP или REST сервиса - возможны иные варианты, если они совместимы с .NET).
    Заранее спасибо, надеюсь на ваше понимание.
     
  11. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
  12. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    На document приходит ответ:
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><viewResponse xmlns="urn:game"></viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    А на rpc приходит это:
    Код (Text):
    1. Вырезано по причине бессмысленности :)
    Во всех вариантах использовал literal, т.к. с encoded VS работать отказывается :(
    Код nuSOAP:
    PHP:
    1. <?php
    2. //Настройки подключения к БД
    3. $mysqlhost = "localhost";
    4. $mysqluser = "root";
    5. $mysqlpass = "";
    6. $mysqlbase = "genom162_alone";
    7.  
    8. $main_conn = mysql_connect ($mysqlhost,$mysqluser,$mysqlpass,$mysqlbase);
    9. mysql_select_db($mysqlbase, $main_conn);
    10. mysql_query('SET character_set_database = cp1251'); mysql_query('SET NAMES cp1251');
    11.  
    12. function sqla($q)
    13. {
    14.     return mysql_fetch_array(sql($q));
    15. }
    16. // Подключаем код NuSOAP
    17. require_once('nusoap.php');
    18. // Создаем экщемпляр сервиса
    19. $server = new soap_server();
    20. // Инициализируем поддержку WSDL
    21. $server->configureWSDL('game', 'urn:game');
    22. // Устанавливаем пространство имен с префиксом tns для WSDL-схемы
    23. $server->wsdl->schemaTargetNamespace = 'urn:game';
    24. //Опа- вот она моя беда - кодировка (не забыть!!!)
    25.  $server->soap_defencoding = 'utf-8';
    26. //Одна игра
    27. $server->wsdl->addComplexType(
    28.     'oneGame',
    29.     'complexType',
    30.     'struct',
    31.     'all',
    32.     '',
    33.     array(
    34.         'id' => array('name' => 'id', 'type' => 'xsd:int'),
    35.         'user1' => array('name' => 'user1', 'type' => 'xsd:string'),
    36.         'user2' => array('name' => 'user2', 'type' => 'xsd:string'),
    37.         'money' => array('name' => 'money', 'type' => 'xsd:int'),
    38.         'typeG' => array('name' => 'typeG', 'type' => 'xsd:string'),
    39.         'status' => array('name' => 'status', 'type' => 'xsd:int'),
    40.         'winner' => array('name' => 'winner', 'type' => 'xsd:string')
    41.          )
    42. );
    43. //Список игр
    44.  
    45. /*
    46. $server->wsdl->addComplexType(
    47.     'listOfGames',
    48.     'complexType',
    49.     'array',
    50.     '',
    51.     'SOAP-ENC:Array',
    52.     array(),
    53.     array(
    54.         array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:oneGame[]')
    55.     ),
    56.     'tns:oneGame'
    57. );
    58. */
    59. /*
    60. $server->wsdl->addComplexType(
    61. 'listOfGames',
    62. 'complexType',
    63. 'array',
    64. '',
    65. 'SOAP-ENC:Array',
    66. array(
    67. array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:oneGame[]')
    68. ),
    69. 'tns:oneGame'
    70. );
    71. */
    72.  
    73. $server->wsdl->addComplexType(
    74. 'listOfGames',
    75. 'complexType',
    76. 'array',
    77. 'all',
    78. '',
    79. 'desc' => array( 'name' => 'desc',
    80. 'type' => 'tns:oneGame',
    81. 'minOccurs' => '0',
    82. 'maxOccurs' => 'unbounded')
    83. )
    84. );
    85.  
    86.  /*
    87.  void addComplexType (
    88.  string $name,
    89.   [string $typeClass = 'complexType'],
    90.  [string $phpType = 'array'],
    91.   [string $compositor = ''],
    92.    [string $restrictionBase = ''],
    93.     [array $elements = array()],
    94.  [array $attrs = array()],
    95.   [string $arrayType = ''])
    96.   */
    97. //Камень-Ножницы-Бумага
    98. $server->wsdl->addComplexType(
    99.     'knb',
    100.     'complexType',
    101.     'struct',
    102.     'all',
    103.     '',
    104.     array(
    105.         'id' => array('name' => 'id', 'type' => 'xsd:int'),
    106.         'idGame' => array('name' => 'idGame', 'type' => 'xsd:int'),
    107.         'c1' => array('name' => 'c1', 'type' => 'xsd:int'),
    108.         'c2' => array('name' => 'c2', 'type' => 'xsd:int')
    109.          )
    110. );    
    111. // Регистрируем предоставляемый метод
    112. $server->register('login',                    // название метода
    113.     array('user'=>'xsd:string','pass'=>'xsd:string'),          // входные параметры
    114.     array('return'=>'xsd:string'),    // выходные параметры
    115.     'urn:game',                         // пространство имен
    116.     'urn:game#login',                   // soapaction
    117.     'rpc',                                    // стиль
    118.     'literal',                                // использование
    119.     'Login to the game server'        // документация
    120. );
    121.  
    122. $server->register('view',                    // название метода
    123.     array('user'=>'xsd:string','pass'=>'xsd:string'),          // входные параметры
    124.     array('return'=>'tns:listOfGames'),    // выходные параметры
    125.     'urn:game',                         // пространство имен
    126.     'urn:game#view',                   // soapaction
    127.     'rpc',                                    // стиль
    128.     'literal',                                // использование
    129.     'List of games'        // документация
    130. );
    131.  
    132.  
    133. // Используем HTTP-запрос чтобы вызвать сервис
    134. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
    135. $server->service($HTTP_RAW_POST_DATA);
    136.  
    137.  
    138.  
    139. // Определяем метод как функцию PHP
    140. function login($user,$pass) {
    141. $pers = mysql_fetch_array(mysql_query ("SELECT user,pass,uid FROM `users` WHERE `smuser`=LOWER('".addslashes($user)."') and `pass`='".(md5($pass))."'"));
    142. if($pers){
    143.         return "good";
    144.     }
    145.     else {
    146.         return "bad";
    147. }
    148. }
    149. function view($user,$pass) {
    150.  $pers = mysql_fetch_array(mysql_query ("SELECT user,pass,uid FROM `users` WHERE `smuser`=LOWER('".addslashes($user)."') and `pass`='".(md5($pass))."'"));
    151.     if($pers){
    152.         $games = mysql_fetch_array(mysql_query ("SELECT * FROM `games`"));
    153.        
    154.         $results = array();
    155.         foreach ($games as $game) {
    156.             $tempArray = array('id' => $game["id"],
    157.                     'user1' => $game["user1"],
    158.                     'user2' => $game["user2"],
    159.                     'money' => $game["money"],
    160.                     'typeG' => $game["typeG"],
    161.                     'status' => $game["status"],
    162.                     'winner' => $game["winner"]
    163.             );
    164.         array_push($results, $tempArray);
    165.         }
    166.         return $results;
    167.     }
    168.     else {
    169.         return new soap_fault('SERVER', '', 'Login plz.');
    170.     }
    171. }
    172. ?>
    И вот дамп таблицы, из которой берутся данные (изаначально предполагается, чт острок будет больше):
    [sql]
    CREATE TABLE IF NOT EXISTS `games` (
    `id` bigint(20) unsigned NOT NULL DEFAULT '0',
    `user1` varchar(10) NOT NULL DEFAULT '',
    `user2` varchar(10) NOT NULL DEFAULT '',
    `money` bigint(20) NOT NULL DEFAULT '0',
    `typeG` varchar(10) NOT NULL DEFAULT '',
    `status` bigint(20) NOT NULL DEFAULT '0',
    `winner` varchar(10) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

    INSERT INTO `games` (`id`, `user1`, `user2`, `money`, `typeG`, `status`, `winner`) VALUES
    (0, 'LiTR', 'Teon', 15, '1', 0, 'LiTR');[/sql]

    ПС:
    в коде сервиса не удалял комменты, чтобы было видно - эти варианты я уже пробовал, но они не работают :(
     
  13. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    во-первых, отформатируйте свой XML - читать и отвечать невозможно.


    А во-вторых, ссылку я видимо давал для фонарного столба...

    Поэтому с советами завязываю. Всего доброго.
     
  14. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    1. Это не мой XML - я его не ждал и просто словил снифером. (удалил, чтобы не мешало - но некоторая закономерность там прослеживалась - так появлялись буквы L и T из БД)
    2. Я зря старался расписывая и используя все варианты кодирования сообщений?
    Если вы не поняли, то для меня применим лишь вариант RPC/literal (в этой реализации, по крайней мере).
    Про ссылку: там текст довольно сложный для восприятия. На сколько я понял (пречитав) - я изначально юзаю wrapped стиль. Но я не уверен, что знание отличий wrapped от non-wrapped даст мне проблеск идей для решения насущных проблем. Хотя я могу ошибаться, но мне кажется, что вы меня толкаете не по той дорожке.
    ПС:
    вы один на этом форуме разбираетесь в SOAP/WSDL или просто другие брезгуют общаться со мной?
     
  15. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    Еще 2-3 человека скорее всего разбираются(они не сильно часто бывают на форуме), остальные скорее всего нет.
    Лучше прямо спросить у остальных - разбираются ли они.

    Может и есть еще кто-то, но он тщательно скрывается.

    Помочь вам можно только одним способом - или имея опыт работы таким же методом как у вас (я с NuSOAP & Silverlight не работал)
    Или взяв в руки спецификации WS-I, генерируемый вами WSDL, Request/Response пакеты и садится это дебажить.

    Вот это
    Говорит о том, что или используется некорректный WSDL файл или подается серверу некорректная структура.
    Т.е. там ошибки и сервер не кодирует сообщение в нужном виде.
    Попробуйте Eclipse там есть редактор WSDL с автовалидацией (хотя и не совсем корректной)

    плюс в нем же можно сразу тестировать свой сервис запросами и смотреть ответы.
    или как вариант погуглить и скачать SoapUI
     
  16. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    1. SoapUI уже давно установлена, но пока не пробовал юзать. В качестве аналога подойдёт Zend Studio 7.0beta? (там есть вариант работы с WSDL, правда нету генерации WSDL из PHP класса - или я не нашёл, хотя в 6+ было) Эклипс где-то есть, но довольно старый (года 3).
    2. Суть моих проблем в передаче массивов(не проверял) и многомерных массивов(точнее массивов структур). Может в zend framework это реализовано более очевидно или также неявно? Или есть более удобные способы кодирования данных с межплатформенным обменом?
     
  17. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    подойдет. В том числе и вместо Eclipse

    Т.е. их не отдает ваш сервер?
    Тогда 100% правьте свой wsdl.
    Лучше всего если вы его получите в виде файла и будете смотреть глазами что там есть.

    Вот это http://www.w3.org/TR/wsdl отличная штука, я нашел там все что нужно в свое время.
     
  18. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    1. Решил сделать так, чтобы метод view возвращал не массив структур, а просто одну структуру.
    Переделал функцию view:
    PHP:
    1. function view($user,$pass) {
    2.         $game = mysql_fetch_array(mysql_query ("SELECT * FROM `games`"));
    3.          $results = array();
    4.        // foreach ($games as $game) {
    5.             $results = array('id' => $game->id,
    6.                     'user1' => $game->user1,
    7.                     'user2' => $game->user2,
    8.                     'money' => $game->money,
    9.                     'typeG' => $game->typeG,
    10.                     'status' => $game->status,
    11.                     'winner' => $game->winner
    12.                     );
    13.  
    14.         return $results;
    15.  
    16. }
    Вернуло:
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:viewResponse xmlns:ns1="urn:game"><return><id/><user1/><user2/><money/><typeG/><status/><winner/></return></ns1:viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    2. Переделал опять:
    PHP:
    1. function view($user,$pass) {
    2.         $game = mysql_fetch_array(mysql_query ("SELECT * FROM `games`"));
    3.          $results = array();
    4.        // foreach ($games as $game) {
    5.             $results = array('id' => "0",
    6.                     'user1' => "LiTR",
    7.                     'user2' => "Teon",
    8.                     'money' => "15",
    9.                     'typeG' => "0",
    10.                     'status' => "0",
    11.                     'winner' => "LiTR"
    12.                     );
    13.  
    14.         return $results;
    15.  
    16. }
    Вернуло:
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:viewResponse xmlns:ns1="urn:game"><return><id>0</id><user1>LiTR</user1><user2>Teon</user2><money>15</money><typeG>0</typeG><status>0</status><winner>LiTR</winner></return></ns1:viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    На клиенте всё отлично поймало. Наверное, я просто плохо обращаюсь с массивами.
    3. Переделал ещё разок:
    PHP:
    1. function view($user,$pass) {
    2.         $game = mysql_fetch_array(mysql_query ("SELECT * FROM `games`"));
    3.          $results = array();
    4.        // foreach ($games as $game) {
    5.             $results = array('id' => $game["id"],
    6.                     'user1' => $game["user1"],
    7.                     'user2' => $game["user2"],
    8.                     'money' => $game["money"],
    9.                     'typeG' => $game["typeG"],
    10.                     'status' => $game["status"],
    11.                     'winner' => $game["winner"]
    12.                     );
    13.  
    14.         return $results;
    15.  
    16. }
    Вернуло всё как и надо:
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:viewResponse xmlns:ns1="urn:game"><return><id>0</id><user1>LiTR</user1><user2>Teon</user2><money>15</money><typeG>1</typeG><status>0</status><winner>LiTR</winner></return></ns1:viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    4. А как на PHP заполнить многомерный массив? Так чтобы к нему потом было легко обращаться?
    Т.е. можно наполнять каждый массив как в последнем примере, а потом каким образом их всех слаживать в большой? Как это лучше реализовать, чтобы не было проблем с сериализацией и последующим обращением к данным?
    К текущему одномерному массиву я обращаюсь вот так:
    обращаюсь к значению "user1" - e.Result.user1 (VS создала прокси и знает, что данные придут в виде структуры oneGame - я могу обращаться к результату как к структуре, забирая каждое значение по отдельности - довольно удобно)
    Есть, конечно, вариант при первом запросе посчитать кол-во строк в таблице, а потом каждую тянуть отдельно, но мне кажется, что это бред бедного студента :)
    Я вот думаю: ключ в этом массиве desc, а значение - структура. Наверное надо заполнять ключи как id. Хотя немного не понимаю как.
    6.
    Сделал вот так:
    PHP:
    1. function view($user,$pass) {
    2.         $game = mysql_fetch_array(mysql_query ("SELECT * FROM `games`"));
    3.          $results = array();
    4.         $result=array();
    5.        // foreach ($games as $game) {
    6.             $result = array('id' => $game["id"],
    7.                     'user1' => $game["user1"],
    8.                     'user2' => $game["user2"],
    9.                     'money' => $game["money"],
    10.                     'typeG' => $game["typeG"],
    11.                     'status' => $game["status"],
    12.                     'winner' => $game["winner"]
    13.                     );
    14.             $results=array('desc'=>$result);
    15. //}
    16.         return $results;
    17. }
    И получил:
    Код (Text):
    1.  
    2. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:viewResponse xmlns:ns1="urn:game"><return><item><id>0</id><user1>LiTR</user1><user2>Teon</user2><money>15</money><typeG>1</typeG><status>0</status><winner>LiTR</winner></item></return></ns1:viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    Вот только не пойму, почему если пытаться разобрать каждую строку(снять комменты и заносить значения таблицы в games) - возвращает белиберду.
     
  19. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
     
  20. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Мне стыдно, конечно, но я не так заносил значения в массив из БД :)
    Вот так работает, за исключением одного пункта - выдаёт только последнюю строку из БД - т.е. я неправильно заполняю главный многомерный массив :(
    PHP:
    1. function view($user,$pass) {
    2.         $games = mysql_query("SELECT * FROM `games`");
    3.         $results = array();
    4.         $result=array();
    5.         for($i=0; $i<mysql_num_rows($games); $i++){
    6.             $game=mysql_fetch_array($games);
    7.             $result = array('id' => $game["id"],
    8.                     'user1' => $game["user1"],
    9.                     'user2' => $game["user2"],
    10.                     'money' => $game["money"],
    11.                     'typeG' => $game["typeG"],
    12.                     'status' => $game["status"],
    13.                     'winner' => $game["winner"]
    14.                     );
    15.             $results=array('desc'=>$result);
    16. }
    17.         return $results;
    18. }
    Может подскажите как заносить $result в $results?
    WSDL можно получить тут - по ссылке WSDL или просто добавив к ссылке ?wsdl.
    Всё... нашёл. Вот решение:
    PHP:
    1.  
    2. function view($user,$pass) {
    3.         $games = mysql_query("SELECT * FROM `games`");
    4.         $results = array();
    5.         $result=array();
    6.         for($i=0; $i<mysql_num_rows($games); $i++){
    7.             $game=mysql_fetch_array($games);
    8.             $result = array('id' => $game["id"],
    9.                     'user1' => $game["user1"],
    10.                     'user2' => $game["user2"],
    11.                     'money' => $game["money"],
    12.                     'typeG' => $game["typeG"],
    13.                     'status' => $game["status"],
    14.                     'winner' => $game["winner"]
    15.                     );
    16.             array_push($results, $result);
    17. }
    18.         return $results;
    19. }
    20. ?>
    Приходит результат:
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:viewResponse xmlns:ns1="urn:game"><return><item><id>0</id><user1>LiTR</user1><user2>Teon</user2><money>15</money><typeG>1</typeG><status>0</status><winner>LiTR</winner></item><item><id>1</id><user1>dsgfwg</user1><user2>wgeg</user2><money>213</money><typeG>2</typeG><status>0</status><winner>dsgsg</winner></item></return></ns1:viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
     
  21. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    $results[]=array
     
  22. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Да... так правильно :)
    Ответ выглядит так:
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:viewResponse xmlns:ns1="urn:game"><return><item><desc><id>0</id><user1>LiTR</user1><user2>Teon</user2><money>15</money><typeG>1</typeG><status>0</status><winner>LiTR</winner></desc></item><item><desc><id>1</id><user1>dsgfwg</user1><user2>wgeg</user2><money>213</money><typeG>2</typeG><status>0</status><winner>dsgsg</winner></desc></item></return></ns1:viewResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
    Если честно, то мне немного мешает <item>. Можно ли сделать так, чтобы его не было в ответе?
     
  23. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Вот полностью WSDL:
    Код (Text):
    1. <definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:game" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:game">
    2. <types>
    3. <xsd:schema targetNamespace="urn:game"
    4. >
    5.  <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
    6.  <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
    7.  <xsd:complexType name="oneGame">
    8.   <xsd:all>
    9.    <xsd:element name="id" type="xsd:int"/>
    10.    <xsd:element name="user1" type="xsd:string"/>
    11.    <xsd:element name="user2" type="xsd:string"/>
    12.    <xsd:element name="money" type="xsd:int"/>
    13.    <xsd:element name="typeG" type="xsd:string"/>
    14.    <xsd:element name="status" type="xsd:int"/>
    15.    <xsd:element name="winner" type="xsd:string"/>
    16.   </xsd:all>
    17.  </xsd:complexType>
    18.  <xsd:complexType name="listOfGames">
    19.   <xsd:all>
    20.    <xsd:element name="desc" type="tns:oneGame" minOccurs="0" maxOccurs="unbounded"/>
    21.   </xsd:all>
    22.  </xsd:complexType>
    23.  <xsd:complexType name="knb">
    24.   <xsd:all>
    25.    <xsd:element name="id" type="xsd:int"/>
    26.    <xsd:element name="idGame" type="xsd:int"/>
    27.    <xsd:element name="c1" type="xsd:int"/>
    28.    <xsd:element name="c2" type="xsd:int"/>
    29.   </xsd:all>
    30.  </xsd:complexType>
    31. </xsd:schema>
    32. </types>
    33. <message name="loginRequest">
    34.   <part name="user" type="xsd:string" />
    35.   <part name="pass" type="xsd:string" /></message>
    36. <message name="loginResponse">
    37.   <part name="return" type="xsd:string" /></message>
    38. <message name="viewRequest">
    39.   <part name="user" type="xsd:string" />
    40.   <part name="pass" type="xsd:string" /></message>
    41. <message name="viewResponse">
    42.   <part name="return" type="tns:listOfGames" /></message>
    43. <portType name="gamePortType">
    44.   <operation name="login">
    45.     <documentation>Login to the game server</documentation>
    46.     <input message="tns:loginRequest"/>
    47.     <output message="tns:loginResponse"/>
    48.   </operation>
    49.   <operation name="view">
    50.     <documentation>List of games</documentation>
    51.     <input message="tns:viewRequest"/>
    52.     <output message="tns:viewResponse"/>
    53.   </operation>
    54. </portType>
    55. <binding name="gameBinding" type="tns:gamePortType">
    56.   <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    57.   <operation name="login">
    58.     <soap:operation soapAction="urn:game#login" style="rpc"/>
    59.     <input><soap:body use="literal" namespace="urn:game"/></input>
    60.     <output><soap:body use="literal" namespace="urn:game"/></output>
    61.   </operation>
    62.   <operation name="view">
    63.     <soap:operation soapAction="urn:game#view" style="rpc"/>
    64.     <input><soap:body use="literal" namespace="urn:game"/></input>
    65.     <output><soap:body use="literal" namespace="urn:game"/></output>
    66.   </operation>
    67. </binding>
    68. <service name="game">
    69.   <port name="gamePort" binding="tns:gameBinding">
    70.     <soap:address location="http://alone.iam.by/SOAP/game.php"/>
    71.   </port>
    72. </service>
    73. </definitions>
    Мне кажется, или <item> "вылазит" в процессе наполнения многомерного массива?
     
  24. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.507
    Симпатии:
    2
    Адрес:
    Донецк
    А как должны определятся элементы многомерного массива без второго измерения?
    Передавайте тупо одномерный массив - тогда этого не будет. Но возникнет вопрос с типами элементов массива.
    Да и как определить кому принадлежит
    Код (Text):
    1. <money>15</money>
    2. <money>213</money>
    ?
    Это в PHP массив может содержать произвольные типы в качестве элементов, в других местах это далеко не так.

    Вобщем я такого извращения не пробовал - можете поэкспериментировать.
     
  25. cheater

    cheater Активный пользователь

    С нами с:
    13 мар 2010
    Сообщения:
    27
    Симпатии:
    0
    Адрес:
    Минск
    Просто VS сгенерила прокси-класс по WSDL, но я могу лишь обратиться к result.desc :( С учётом того, что все группы элементов входят в desc, то не вижу смысла заново их влаживать в item. Другое дело - как сделать, чтобы не было item?
    Ы) Придумал, пока писал вам :)
    Я просто передрал объявление массива:
    PHP:
    1. $server->wsdl->addComplexType(
    2. 'listOfGames',
    3. 'complexType',
    4. 'array',
    5. 'all',
    6. '',
    7. 'item' => array( 'name' => 'item',
    8. 'type' => 'tns:oneGame',
    9. 'minOccurs' => '0',
    10. 'maxOccurs' => 'unbounded')
    11. )
    12. );
    И поставил свой вариант:
    PHP:
    1. array_push($results, $result);
    Т.е. теперь вместо desc item- и пусть себе пхнёт массив <item> - всёравно уже объявлено в WSDL :)
    Теперь буду думать как разграничить Каждый item друг от друга. Но главное на данный момент - могу получать данные из первой строки :)