【发布时间】:2015-05-28 15:25:09
【问题描述】:
我正在尝试通过 PHP 创建对 WSDK 服务的 XML SOAP 请求 - 我的代码如下:
<?php
//WSSE Authentication Header Object
class WsseAuthHeader extends SoapHeader {
private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
function __construct($user, $pass, $ns = null) {
if ($ns) {
$this->wss_ns = $ns;
}
$auth = new stdClass();
$auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
$auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);
$username_token = new stdClass();
$username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);
$security_sv = new SoapVar(
new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns), SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
parent::__construct($this->wss_ns, 'Security', $security_sv, true);
}
}
//Set WSSE Variables
$username = 'username';
$password = 'pw';
$wsdl = 'wsdlurl';
$wsse_header = new WsseAuthHeader($username, $password);
//Create Soap Client
$client = new SoapClient($wsdl,array("trace" => 1));
//Set SOAP headers
$client->__setSoapHeaders(array($wsse_header));
$xml_text = "<v1:MembershipNumber>999999</v1:MembershipNumber>";
$v1 = new SoapVar($xml_text, 147);
//Create Object
$request = array(
"MembershipNumber" => $v1,
);
var_dump($request);
//$results = $client->GetMemberNumber($request);
$results = $client->__soapCall('GetMemberNumber', array('MemberNumberRequest'=>$request));
//Print Results
echo "<br /><br />REQUEST:\n" . $client->__getLastRequest() . "<br /><br />";
echo "REQUEST HEADERS:\n" . $client->__getLastRequestHeaders() . "<br /><br />";
echo "RESPONSE:\n" . $client->__getLastResponse() . "<br /><br />";
echo "RESPONSE HEADERS:\n" . $client->__getLastResponseHeaders() . "<br /><br />";
echo "Var Dump: "; var_dump($results);
?>
XML 请求应采用以下格式:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="schemaurl">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1">
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<v1:MemberNumberRequest>
<v1:MemberNumber>?</v1:MemberNumber>
</v1:MemberNumberRequest>
</soapenv:Body>
</soapenv:Envelope>
目前我收到错误消息:
“致命错误:未捕获的 SoapFault 异常:[env:Server] Invalid Credentials”
- 如果我使用常规数组而不是 SoapVar,我不会收到凭据错误 - 我的用户名和密码绝对正确。
如何使用 PHP 将请求转换为正确的 XML 请求格式?
【问题讨论】:
-
错误消息表明凭据无效,因此很可能 WsseAuthHeader 未发送正确的凭据或对它们进行编码(或两者)有问题。您从哪里复制 WsseAuthHeader 代码?有报道说在那里工作吗?这是不断自动测试的吗?
-
感谢您的帮助。最后问题出在服务端,我没有得到正确的测试数据集。 |所以凭据和调用是正确的。
-
尽管对于任何偶然发现这一点的人-开发人员更改了服务上的某些内容-最初这有效:
//Set SOAP headers $client->__setSoapHeaders(array($wsse_header)); $results = $client->__soapCall('FunctionName', array('FunctionRequest'=>$request));然后我不得不将其更改为:$results = $client->__soapCall('FunctionName', array('FunctionRequest'=>$request), null, array($wsse_header))最后我不得不回到让它工作的第一个选项,我不确定发生了什么变化。 -
您可以将您的解决方案作为答案留在下方,并将其标记为答案。这将使您的解决方案清晰可见,并且对您有效。