2016-08-16 114 views
2

我在PHP中创建SOAP请求以连接到Campaigner(电子邮件营销工具)并上传联系人时遇到问题,但我可以使用一些帮助。我正在使用的API不断响应一个Null对象。这里是我工作过的XML(工作时,我使用了SoapUI):PHP SOAP请求问题

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="https://ws.campaigner.com/2013/01"> 
<soapenv:Header/> 
<soapenv:Body> 
    <ns:ImmediateUpload> 
    <!--Optional:--> 
    <ns:authentication> 
     <!--Optional:--> 
     <ns:Username>username</ns:Username> 
     <!--Optional:--> 
     <ns:Password>password</ns:Password> 
    </ns:authentication> 
    <ns:UpdateExistingContacts>true</ns:UpdateExistingContacts> 
    <ns:TriggerWorkflow>false</ns:TriggerWorkflow> 
    <!--Optional:--> 
    <ns:contacts> 
     <ns:ContactData> 
      <ns:ContactKey> 
       <ns:ContactId>0</ns:ContactId> 
       <ns:ContactUniqueIdentifier>[email protected]</ns:ContactUniqueIdentifier> 
      </ns:ContactKey> 
      <ns:EmailAddress>[email protected]</ns:EmailAddress> 
      <ns:FirstName>Steve</ns:FirstName> 
      <ns:LastName>Rogers</ns:LastName> 
      <ns:Status>Subscribed</ns:Status> 
      <ns:MailFormat>Both</ns:MailFormat> 
      <ns:IsTestContact>0</ns:IsTestContact> 
     </ns:ContactData> 
    </ns:contacts> 
    </ns:ImmediateUpload> 

这是我的PHP代码:

<?php 
$wsdl = "https://ws.campaigner.com/2013/01/contactmanagement.asmx?wsdl"; 

$trace = true; 
$exceptions = true; 

$Username = "username"; 
$Password = "password"; 
$UpdateExistingContacts = true; 
$TriggerWorkflow = false; 
$ContactId = 0; 
$ContactUniqueIdentifier= "[email protected]"; 
$EmailAddress = "[email protected]"; 
$FirstName = "Steve"; 
$LastName = "Rogers"; 
$Status = "Subscribed"; 
$MailFormat = "Both"; 
$IsTestContact = 0; 


$params = array (
"Username" => $Username, 
"Password" => $Password, 
"UpdateExistingContacts" => $UpdateExistingContacts, 
"TriggerWorkflow" => $TriggerWorkflow, 
"ContactId" => $ContactId, 
"ContactUniqueIdentifier" => $ContactUniqueIdentifier, 
"EmailAddress" => $EmailAddress, 
"FirstName" => $FirstName, 
"LastName" => $LastName, 
"Status" => $Status, 
"MailFormat" => $MailFormat, 
"IsTestContact" => $IsTestContact 
); 

try{ 
$client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions)); 
$response = $client->__call("ImmediateUpload", array($params)); 
} catch (Exception $e){ 
echo "error"; 
echo $e ->getMessage(); 
echo 'Last Response: '.$client->__getLastResponse(); 
} 

var_dump($response); 
?> 

这里是我回来的响应:

object(stdClass)#2 (0) {} 

这绝对是我的一个格式问题,因为我得到了一个成功的回应使用SoapUI写入Campaigner,并且只有在尝试通过PHP执行操作时才会出现此错误。我感谢您提供的任何帮助!

谢谢 洛根

更新: 我能弄清楚,它是我的构建请求的方式......下面是实际的响应回:

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Header><ResponseHeader xmlns="https://ws.campaigner.com/2013/01"> 
<ErrorFlag>true</ErrorFlag> 
<ReturnCode>U_4.5.1.3_USERNAME-AND-PASSWORD-REQUIRED</ReturnCode> 
<ReturnMessage>Username and Password is required.</ReturnMessage> 
</ResponseHeader> 
</soap:Header><soap:Body><ImmediateUploadResponse xmlns="https://ws.campaigner.com/2013/01" /> 
</soap:Body> 
</soap:Envelope> 

回答

0

对SOAP调用进行故障排除

通过使用SoapUI创建已知的工作请求,您已经领先于游戏。好工作。
您怀疑请求的格式在PHP中不正确。要验证,检查原始SOAP XML与var_dump($client->__getLastRequest());,看看你会得到什么:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:ns1="https://ws.campaigner.com/2013/01"> 
    <SOAP-ENV:Body> 
    <ns1:ImmediateUpload> 
     <ns1:UpdateExistingContacts>true</ns1:UpdateExistingContacts> 
     <ns1:TriggerWorkflow>false</ns1:TriggerWorkflow> 
    </ns1:ImmediateUpload> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

绝对不像你了SoapUI请求。那么为什么会这样呢?让我们一起来看看输出,并寻找ImmediateUpload:

array(32) { 
    [0]=> 
    string(68) "ImmediateUploadResponse ImmediateUpload(ImmediateUpload $parameters)" 

所以我们在这里看到,该方法ImmediateUpload()接受型ImmediateUpload的一个变量$参数。

但是ImmediateUpload的结构是什么样的?让我们看一看的var_dump($client->__getTypes());输出并查找类型:

array(88) { 
    [0]=> 
    string(212) "struct ImmediateUpload { 
Authentication authentication; 
boolean UpdateExistingContacts; 
boolean TriggerWorkflow; 
ArrayOfContactData contacts; 
ArrayOfInt globalAddToGroup; 
ArrayOfInt globalRemoveFromGroup; 
}" 

ImmediateUpload是具有六个字段的结构:1认证,2个布尔值,和3个阵列。所以我们传入的$参数对象必须遵循这个结构。我们可以进一步检查__getTypes()来寻找数据类型的其余部分:

[1]=> 
    string(61) "struct Authentication { 
string Username; 
string Password; 
}" 
    [2]=> 
    string(55) "struct ArrayOfContactData { 
ContactData ContactData; 
}" 
    [3]=> 
    string(357) "struct ContactData { 
ContactKey ContactKey; 
NullableElement EmailAddress; 
NullableElement FirstName; 
NullableElement LastName; 
NullableElement PhoneNumber; 
NullableElement Fax; 
ContactStatus Status; 
ContactMailFormat MailFormat; 
boolean IsTestContact; 
ArrayOfCustomAttribute CustomAttributes; 
ArrayOfInt AddToGroup; 
ArrayOfInt RemoveFromGroup; 
}" 

修复代码

现在我们将修复代码。让我们构建一个看起来像ImmediateUpload的数据结构。为了简单起见,我将使用数组而不是类(无论哪种方式都可以在PHP中使用)。让我们创建一个开始接触:

$contact1 = array(
    "ContactKey"  => array("ContactId" => $ContactId, "ContactUniqueIdentifier" => $ContactUniqueIdentifier), 
    "EmailAddress"  => $EmailAddress, 
    "FirstName"   => $FirstName, 
    "LastName"   => $LastName, 
    "PhoneNumber"  => array('', true), 
    "Fax"    => array('', true), 
    "Status"   => $Status, 
    "MailFormat"  => $MailFormat, 
    "IsTestContact"  => $IsTestContact, 
    "CustomAttributes" => array(), 
    "AddToGroup"  => array(), 
    "RemoveFromGroup" => array(), 
); 

而现在,我们将构建ImmediateUpload参数:

$params = array (
    'authentication'   => array("Username" => $Username, "Password" => $Password), 
    "UpdateExistingContacts" => $UpdateExistingContacts, 
    "TriggerWorkflow"   => $TriggerWorkflow, 
    "contacts"    => array($contact1), 
    "globalAddToGroup"  => array(), 
    "globalRemoveFromGroup" => array(), 
); 

再次运行代码。现在检查请求的XML进行调用后,它应该看起来非常相似,你的了SoapUI要求:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://ws.campaigner.com/2013/01"> 
<SOAP-ENV:Body> 
    <ns1:ImmediateUpload> 
     <ns1:authentication> 
      <ns1:Username>username</ns1:Username> 
      <ns1:Password>password</ns1:Password> 
     </ns1:authentication> 
     <ns1:UpdateExistingContacts>true</ns1:UpdateExistingContacts> 
     <ns1:TriggerWorkflow>false</ns1:TriggerWorkflow> 
     <ns1:contacts> 
      <ns1:ContactData> 
       <ns1:ContactKey> 
        <ns1:ContactId>0</ns1:ContactId> 
        <ns1:ContactUniqueIdentifier>[email protected]</ns1:ContactUniqueIdentifier> 
       </ns1:ContactKey> 
       <ns1:EmailAddress>[email protected]</ns1:EmailAddress> 
       <ns1:FirstName>Steve</ns1:FirstName> 
       <ns1:LastName>Rogers</ns1:LastName> 
       <ns1:PhoneNumber/> 
       <ns1:Fax/> 
       <ns1:Status>Subscribed</ns1:Status> 
       <ns1:MailFormat>Both</ns1:MailFormat> 
       <ns1:IsTestContact>false</ns1:IsTestContact> 
       <ns1:CustomAttributes/> 
       <ns1:AddToGroup/> 
       <ns1:RemoveFromGroup/> 
      </ns1:ContactData> 
     </ns1:contacts> 
     <ns1:globalAddToGroup/> 
     <ns1:globalRemoveFromGroup/> 
    </ns1:ImmediateUpload> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

你仍然会得到验证错误,但现在你是一步步接近获得呼叫工作。