PHP 5.3 SOAP 请求是如何形成的?
我正在尝试编写一些代码来与 SmarterMail API 对话,但我似乎无法使 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”。
我应该注意到,服务器接受请求并返回一条有关身份验证失败的消息。服务器上有一个内置的 SOAP 请求测试器,当请求符合给定示例时,它可以正常工作。
我在 PHP 文档和 Google 中查找到的所有内容似乎都表明它不应该这么困难。 :(
非常感谢任何帮助。
注意:我在 FreeBSD 上的 Apache 2.2 上运行 PHP 5.3.8,今天通过端口构建和安装。
回答后编辑:
感谢下面 Gian 的回答,我'已经开始工作并大大简化了代码:
<?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>";
I am trying to write some code to talk to the SmarterMail API, but I can't seem to make PHP format the request properly. The [ugly] code I have so far is:
<?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>";
?>
For reference, the WSDL for this function is:
<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>
The example request given is:
<?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>
But the request generated by my code is:
<?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>
You can see that the username and password parameters are not contained within the GetAllDomains section for some reason. As well, in the code you can see that I have to pass a dummy parameter in first because whatever is first does not show up in the request. Also, I cannot simply pass in an associative array because the keys are not used as parameter names, it puts in 'param1' and 'param2' instead.
I should note that the server accepts the request and spits back a message about the auth failing. There is a built-in SOAP request tester on the server, and when the request fits the given example it works normally.
Everything I've looked up in the PHP docs and through Google seems to indicate that it should not be this difficult. :(
Any help is GREATLY appreciated.
note: I am running PHP 5.3.8 on Apache 2.2 on FreeBSD, built and installed via ports today.
post-answer-edit:
Thanks to Gian's answer below I've gotten this working and greatly simplified the code:
<?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>";
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我对错误的结束表示歉意。我一开始误解了你想要做什么。
通过筛选
soapCall
文档注释,我建议尝试以下几件事。首先,这个:显然您的参数需要是具有键“参数”的关联数组中的元素。很奇怪吧?
如果做不到这一点,您可能需要将其嵌套得更深!
_
数组条目似乎没有在任何明显的地方记录,但这似乎是 PHP 文档的评论者所建议的。所以也许是这样的:My apologies for the mis-directed close. I misunderstood what you were trying to do at first.
Sifting through the
soapCall
documentation comments, there are a couple things I'd suggest trying. First off, this:Apparently your parameters need to be an element in an associative array with the key 'parameters'. Weird, huh?
Failing that, you may need to nest this even deeper! The
_
array entry does not appear to be documented anywhere obvious, but this seems to be something that the commenters on the PHP docs were suggesting. So maybe this: