Как использовать nuSOAP для сообщений с несколькими пространствами имен - PullRequest
6 голосов
/ 01 апреля 2009

Я пытаюсь получить доступ к WebService, используя nuSOAP (потому что я связан с PHP4 здесь), который использует более 1 пространства имен в сообщении. Это возможно?

Пример сообщения запроса будет выглядеть следующим образом:

<soapenv:Envelope ...
  xmlns:ns1="http://domain.tld/namespace1"
  xmlns:ns2="http://domain.tld/namespace2">
  <soapenv:Header/>
  <soapenv:Body>
    <ns1:myOperation>
      <ns2:Person>
        <ns2:Firstname>..</ns2:Firstname>
        ..
      </ns2:Person>
      <ns1:Attribute>..</ns1:Attribute>
    </ns1:myOperation>
  </soapenv:Body>
</soapenv:Envelope>

Я пытался следующее:

$client = new nusoap_client("my.wsdl", true);
$params = array(
  'Person' => array(
    'FirstName'  => 'Thomas',
    ..
   ),
   'Attribute' => 'foo'
 );

 $result = $client->call('myOperation', $params, '', 'soapAction');

в надежде, что nuSOAP попытается сопоставить эти имена с правильными пространствами имен и узлами. Затем я попытался использовать soapval () для генерации элементов и их пространства имен - но если я вызываю операцию, nuSOAP создает следующий запрос:

<SOAP-ENV:Envelope ...>
  <SOAP-ENV:Body>
    <queryCCApplicationDataRequest xmlns="http://domain.tld/namespace1"/>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Итак, что-то идет не так во время «совпадающей» фазы.

Ответы [ 4 ]

5 голосов
/ 09 апреля 2009

Попробовав сопоставление, я нашел два возможных решения:

1) Не используйте WSDL для создания nusoap_client и soapval () для создания сообщения Это имеет тот недостаток, что сообщение содержит много служебных данных (пространство имен определено в каждом элементе). Не так хорошо.

2) Вместо того чтобы полагаться на сопоставление параметров, создайте свой ответ в xml и поместите все определения префиксов в первый элемент - например,

$params = "<ns1:myOperation xmlns:ns1="..." xmlns:ns2="...">
      <ns2:Person>
        <ns2:Firstname>..</ns2:Firstname>
        ..
      </ns2:Person>
      <ns1:Attribute>..</ns1:Attribute>
    </ns1:myOperation>";

Все еще не очень хорошее решение, но оно работает: -)

4 голосов
/ 09 июня 2010

Опираясь на пост Ирвина, я создал xml вручную, а остальное сделал nusoap. Мой веб-хост не имеет расширения php soap, поэтому мне пришлось использовать nusoap, и веб-сервис, который я пытаюсь использовать, требовал пространства имен для каждого тега (например, для имени пользователя и пароля в моем примере здесь).

<code>require_once('lib/nusoap.php');

$client = new nusoap_client('https://service.somesite.com/ClientService.asmx');
$client->soap_defencoding = 'utf-8';
$client->useHTTPPersistentConnection(); // Uses http 1.1 instead of 1.0
$soapaction = "https://service.somesite.com/GetFoods";

$request_xml = '<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <n1:GetFoods xmlns:n1="https://service.somesite.com">
      <n1:username>banjer</n1:username>
      <n1:password>theleftorium</n1:password>
    </n1:GetFoods>
  </env:Body>
</env:Envelope>
';

$response = $client->send($request_xml, $soapaction, ''); 

echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '
'; echo '

Response

' . htmlspecialchars($client->response, ENT_QUOTES) . '
'; echo '

Debug

' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '
';

Тогда у меня была ошибка, которая сказала:

Notice: Undefined property: nusoap_client::$operation in ./lib/nusoap.php  on line 7674

Итак, я пошел ленивым путем, зашел в nusoap.php и добавил этот код перед строкой 7674, чтобы сделать его счастливым:

    if(empty($this->operation)) {
        $this->operation = "";
    }
1 голос
/ 14 декабря 2010

Еще одним обходом этой проблемы будет изменение функции nusoap_client :: call (). Рядом с этой строкой (7359 в версии 1.123) в nusoap.php:

$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);

Я добавил это:

$nsPrefix = $this->wsdl->getPrefixFromNamespace("other_ns_name");

И это сработало! Поскольку мне нужна была только эта библиотека для одного проекта, я мог жестко закодировать этот хак. В противном случае я бы копал больше и изменил бы функцию, чтобы принимать массив вместо строки для параметра пространства имен.

0 голосов
/ 05 ноября 2009

Да, у меня возникла такая же проблема (нашел ваш q через Google!), И я столкнулся с этим: http://www.heidisoft.com/blog/using-nusoap-consume-net-web-service-10-min Здесь dev создает тело сообщения xml в coe и затем использует nusoap для отправки.

...