Я пытаюсь написать некоторый код, чтобы поговорить с API SmarterMail, но я не могу заставить PHP правильно отформатировать запрос. Код [уродливый], который у меня есть до сих пор:
<?php function array_to_params($in_arr) { $out_arr = array(); foreach( $in_arr as $key => $value ) { $out_arr[] = new SoapParam($value, $key); } return $out_arr; } echo "<pre>"; $soapClient = new SoapClient( "http://mailserver.net/Services/svcDomainAdmin.asmx?WSDL", array('trace' => true) ); var_dump($soapClient->__getTypes());die(); $soap_user_params = array( 'blank' => 'blank', //if I don't have a dummy entry the first parameter doesn't show up. 'AuthUserName' => 'admin', 'AuthPassword' => 'derp' ); $soap_user_params = array_to_params($soap_user_params); $error = FALSE; try { $info = $soapClient->__soapCall("GetAllDomains", $soap_user_params); // $info = $soapClient->GetAllDomains($soap_user_params); //same results } catch (SoapFault $fault) { $error = TRUE; printf("Error %s: %s\n", $fault->faultcode, $fault->faultstring); } if( !$error ) { var_dump($info); echo "\nRequest: " . htmlentities($soapClient->__getLastRequest()); } echo "</pre>"; ?>
Для справки WSDL для этой функции:
<s:element name="GetAllDomains"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="AuthUserName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="AuthPassword" type="s:string"/> </s:sequence> </s:complexType> </s:element>
Приведенный пример запроса:
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetAllDomains xmlns="http://tempuri.org/"> <AuthUserName>string</AuthUserName> <AuthPassword>string</AuthPassword> </GetAllDomains> </soap:Body> </soap:Envelope>
Но запрос, созданный моим кодом:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"> <SOAP-ENV:Body> <ns1:GetAllDomains/> <AuthUserName>admin</AuthUserName> <AuthPassword>derp</AuthPassword> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Вы можете видеть, что параметры имени пользователя и пароля не содержатся в разделе GetAllDomains по какой-либо причине. Кроме того, в коде вы можете увидеть, что мне нужно сначала передать фиктивный параметр, потому что все, что сначала не отображается в запросе. Кроме того, я не могу просто передать ассоциативный массив, потому что ключи не используются как имена параметров, вместо этого они помещаются в 'param1' и 'param2'.
Я должен отметить, что сервер принимает запрос и возвращает обратно сообщение об ошибке auth. На сервере есть встроенный тестер запросов SOAP, и когда запрос соответствует данному примеру, он работает нормально.
Все, что я искал в документах PHP и через Google, похоже, указывает, что это не должно быть так сложно. 🙁
Любая помощь ВОЗМОЖНО высоко ценится.
Примечание. Я запускаю PHP 5.3.8 на Apache 2.2 на FreeBSD, встроенный и установленный через порты сегодня.
пост-ответ-редактирование:
Благодаря ответу Джиана ниже я получил эту работу и значительно упростил код:
<?php echo "<pre>"; $soapClient = new SoapClient( "http://mailserver.net/Services/svcDomainAdmin.asmx?WSDL", array( 'trace' => true ) ); $soap_user_params = array( 'AuthUserName' => 'admin', 'AuthPassword' => 'derp' ); try { $info = $soapClient->__soapCall("GetAllDomains", array( 'parameters' => $soap_user_params ) ); var_dump($info); echo "\nRequest:\n" . htmlentities($soapClient->__getLastRequest()); } catch (SoapFault $fault) { printf("Error %s: %s\n", $fault->faultcode, $fault->faultstring); } echo "</pre>";
Приношу свои извинения за неправильное направление. Я неправильно понял, что вы пытались сделать сначала.
Просеивая комментарии к документации soapCall
, есть несколько вещей, которые я предлагаю попробовать. Прежде всего, это:
$soap_user_params = array( 'parameters' => array ( 'AuthUserName' => 'admin', 'AuthPassword' => 'derp' ) );
По-видимому, ваши параметры должны быть элементом в ассоциативном массиве с ключевыми «параметрами». Странно, да?
В противном случае вам может понадобиться еще глубже вложить это! Элемент _
array не выглядит документированным в любом месте, но это похоже на то, что предлагали комментаторы в документах PHP. Так может быть и это:
$soap_user_params = array( 'parameters' => array ( 'AuthUserName' => array('_' => 'admin'), 'AuthPassword' => array('_' => 'derp') ) );