PHP SoapClient с API SuperPages

#php #api #soap #soap-client

#php #API #soap #soap-клиент

Вопрос:

Итак, я совершенно новичок в SOAP и всей идее, стоящей за ним, но я вынужден разобраться в этом, чтобы работать с API SuperPages. На данный момент я просто пытаюсь разобраться в этом и в том, как выполнять вызовы API. Документацию по API можно найти здесь:http://advertising.superpages.com/spapiweb/v2. Я могу войти в систему через заголовки, но я не совсем понимаю, куда идти дальше. Вот документация для функции, которую я пытаюсь запустить:

 getReportList
  

Метод GetReportList извлекает список отчетов, которые хранятся в данный момент.

Запрос:

 Field Name             Field Type  Field Description    Field
externalTransactionId   string(6)   External Transaction identifier used for logging. Provided by user. Optional
  

Ответ

 <soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns2:getReportListResponse xmlns:ns2="webobjects.reporting.pbap.spmd.com">
     <return>
        <ns2:report>
           <ns2:reportName></ns2:reportName>
           <ns2:reportId></ns2:reportId>
           <ns2:reportType></ns2:reportType>
           <ns2:status></ns2:status>
           <ns2:startDate></ns2:startDate>
           <ns2:endDate></ns2:endDate>
           <ns2:createdDate></ns2:createdDate>
        </ns2:report>
        <ns2:totalRows></ns2:totalRows>
        <ns2:dateCreated></ns2:dateCreated>
        <ns2:internalTransactionId></ns2:internalTransactionId>
     </return>
  </ns2:getReportListResponse>
    </soap:Body>
</soap:Envelope>
  

Мой код:

  $options = array('trace' => true);
 $sp = new SoapClient('http://services.superpages.com/spexternalservicesv3/services/reportingservice?wsdl', $options);
 $header = new SoapHeader('[companyId]', '[username]', '[password]');
 $sp->__setSoapHeaders($header);

 echo "<pre>";
 var_dump($sp->__getFunctions()); //check that I'm at least doing something right
 echo "</pre>";

 $sp->__soapCall("getReportList",array("")); //empty array, because parameter is optional in documentation
  

Мои результаты:

 array(5) {
  [0]=>
  string(59) "getReportURLResponse getReportURL(getReportURL $parameters)"
  [1]=>
  string(83) "scheduleAgencyReportResponse scheduleAgencyReport(scheduleAgencyReport $parameters)"
  [2]=>
  string(65) "scheduleReportResponse scheduleReport(scheduleReport $parameters)"
  [3]=>
  string(59) "deleteReportResponse deleteReport(deleteReport $parameters)"
  [4]=>
  string(62) "getReportListResponse getReportList(getReportList $parameters)"
}


Fatal error: Uncaught SoapFault exception: [soap:Client] Error reading XMLStreamReader. in /home/a2op/public_html/billing/sp/index.php:11 Stack trace: #0 /home/a2op/public_html/billing/sp/index.php(11): SoapClient->__soapCall('getReportList', Array) #1 {main} thrown in /home/a2op/public_html/billing/sp/index.php on line 11
  

Что я здесь делаю не так?


Редактировать

При отладке через

 try {
    var_dump($sp->getReportList());
} catch (SoapFault $exception) {
    var_dump($exception->getMessage());
    var_dump($exception);
}
  

это дамп ошибки

 string(32) "Fault occurred while processing."
object(SoapFault)#5 (8) {
  ["message:protected"]=>
  string(32) "Fault occurred while processing."
  ["string:private"]=>
  string(0) ""
  ["code:protected"]=>
  int(0)
  ["file:protected"]=>
  string(43) "/home/a2op/public_html/billing/sp/index.php"
  ["line:protected"]=>
  int(19)
  ["trace:private"]=>
  array(2) {
    [0]=>
    array(6) {
      ["file"]=>
      string(43) "/home/a2op/public_html/billing/sp/index.php"
      ["line"]=>
      int(19)
      ["function"]=>
      string(6) "__call"
      ["class"]=>
      string(10) "SoapClient"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(2) {
        [0]=>
        string(13) "getReportList"
        [1]=>
        array(0) {
        }
      }
    }
    [1]=>
    array(6) {
      ["file"]=>
      string(43) "/home/a2op/public_html/billing/sp/index.php"
      ["line"]=>
      int(19)
      ["function"]=>
      string(13) "getReportList"
      ["class"]=>
      string(10) "SoapClient"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(0) {
      }
    }
  }
  ["faultstring"]=>
  string(32) "Fault occurred while processing."
  ["faultcode"]=>
  string(11) "soap:Server"
}
  

Редактировать

Вывод XML после запуска

 try{
    var_dump($sp->getReportList());
}catch (SoapFault $exception) {
    var_dump($exception->getMessage());
    var_dump($exception);
}
echo $sp->__getLastRequest();
  

 <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:ns1="webobjects.reporting.pbap.spmd.com">
  <SOAP-ENV:Header>
    <ns1:username>[username]</ns1:username>
    <ns1:password>[password]</ns1:password>
    <ns1:companyId>[companyId]</ns1:companyId>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <ns1:getReportList/>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
  

Ответ №1:

Интересно: никогда не использовал его раньше, но я думаю, что это неправильно:

 $header = new SoapHeader('[companyId]', '[username]', '[password]');
$sp->__setSoapHeaders($header);
  

Я думаю, вы хотите этого:

 $headers = array();
$header[] = new SoapHeader('webobjects.reporting.pbap.spmd.com', 'username', '[username]');
$header[] = new SoapHeader('webobjects.reporting.pbap.spmd.com', 'password', '[password]');
$header[] = new SoapHeader('webobjects.reporting.pbap.spmd.com', 'companyId', '[companyId]');
$sp->__setSoapHeaders($headers);
  

смотрите http://www.php.net/manual/en/soapclient.setsoapheaders.php для setSoapHeaders() вызова с несколькими заголовками, и вам, вероятно, следует выгрузить XML-запрос, чтобы убедиться, что он выглядит как пример на http://advertising.superpages.com/spapiweb/v2?wicket:interface=:11:3: .

Дайте мне знать, если это сработает.

Комментарии:

1. Я попытался сделать заголовки так, как вы предложили. Это не вызвало ошибки и ничего не изменило. Когда я пытаюсь запустить __getLastResponse, __getLastResponseHeaders, __getLastRequest и __getLastRequestHeaders, все они возвращают null. Является ли ложным предположение, что, поскольку _getFunctions() работает, я правильно «регистрируюсь»?

2. __getFunctions вероятно, будет работать нормально в любом случае: я ожидаю, что он поступает из WSDL, который не требует от вас входа в систему. Вы сказали, что ошибок не было (так что это хоть что-то), но вы неправильно вызываете метод. Все, что вам нужно сделать, это $sp->getReportList(); : SoapClient выполняет преобразование вызова функции и вызывает правильную функцию SOAP для вас. Попробуйте это и дайте мне знать, что он говорит.

3. Хм… Я попробовал $sp->getReportList(); и получил эту ошибку: Fatal error: Uncaught SoapFault exception: [soap:Server] Fault occurred while processing. in /home/a2op/public_html/billing/sp/index.php:14 Stack trace: #0 /home/a2op/public_html/billing/sp/index.php(14): SoapClient->__call('getReportList', Array) #1 /home/a2op/public_html/billing/sp/index.php(14): SoapClient->getReportList() #2 {main} thrown in /home/a2op/public_html/billing/sp/index.php on line 14

4. Кроме того, я попытался запустить var_dump(method_exists($sp,'getReportList')); , который вернул false .

5. method_exists не будет работать; также не будет is_callable , поскольку перевод метода выполняется внутри __call функции объекта SoapClient. Вы должны перехватить ошибку следующим образом: try{ $sp->getReportList(); }catch (SoapFault $exception){ var_dump($exception->getMessage); } и посмотреть, что это за сообщение об исключении.