PHP SOAP请求问题

时间:2016-08-16 22:02:37

标签: php soap

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

<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>test@testemail.com</ns:ContactUniqueIdentifier>
           </ns:ContactKey>
           <ns:EmailAddress>test@testemail.com</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= "test@testemail.com";
$EmailAddress = "test@testemail.com";
$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>

1 个答案:

答案 0 :(得分:0)

对SOAP调用进行故障排除

通过使用SoapUI创建已知的工作请求,您已经领先于游戏。干得好。
您怀疑PHP中的请求格式不正确。要验证这一点,请使用var_dump($client->__getLastRequest());检查原始SOAP XML并查看您获得的内容:

<?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请求。那为什么会这样呢?让我们看一下var_dump($client->__getFunctions());的输出并查找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个数组。所以我们传入的$ parameters对象必须遵循这个结构。我们可以进一步检查__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>test@testemail.com</ns1:ContactUniqueIdentifier>
                </ns1:ContactKey>
                <ns1:EmailAddress>test@testemail.com</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>

您仍然会收到身份验证错误,但现在您距离呼叫工作还有一步之遥。