2011-11-24 34 views
1

我想写一些代码来与SmarterMail API交谈,但我似乎无法正确地使PHP格式的请求。的[难看]代码我迄今为止是:PHP 5.3 SOAP请求是如何形成的?

<?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上运行PHP 5.3.8在Apache 2.2,今天建成并通过端口安装

后的答案编辑:

感谢吉安的回答下面我已经得到了这方面的工作,并大大简化了代码:

<?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>"; 
+0

[从PHP消费到.NET SOAP服务与认证]的可能重复(http://stackoverflow.com/questions/7959798/consuming-to-a-net-soap-service -from-php-with-authentication) – Gian

+0

@Gian我真的没有看到连接。尽我所能告诉他的问题是使用SOAP头,但是这个应用程序甚至不需要头部分。 在这个低音API中,用户名和密码作为参数发送给每个需要认证的函数[也就是每个函数],而不是作为头文件的一部分。 – Sammitch

回答

1

我的AP关于错误指导的关闭。我误解了你最初想做的事情。

通过soapCall文档评论筛选,有几件事我建议尝试。首先,这:

$soap_user_params = array(
    'parameters' => array (
     'AuthUserName' => 'admin', 
     'AuthPassword' => 'derp' 
    ) 
); 

显然你的参数需要是关键'参数'的关联数组中的一个元素。奇怪,是吧?

如果不这样做,您可能需要将它嵌套得更深! _数组条目似乎没有记录在任何明显的位置,但这似乎是PHP文档中的评论者所暗示的内容。因此,也许这样的:

$soap_user_params = array(
    'parameters' => array (
     'AuthUserName' => array('_' => 'admin'), 
     'AuthPassword' => array('_' => 'derp') 
    ) 
); 
+0

嵌套在'parameters'数组中已经完成了这个诀窍,尽管我仍然为什么这是必要的而感到困惑。我也尝试过'_'数组,但它们不起作用。 我相信我在'soapCall'文档页面找到了[http://www.php.net/manual/en/soapclient.soapcall.php#89308](您提到的评论),这似乎暗示了这与SOAP服务器是.NET有关。 GDI MS! \ * rantrantrant \ *。 – Sammitch