SOAP PHP&类型数组

时间:2016-11-16 00:41:03

标签: php soap

我是第一个承认我很少使用SOAP的人,但我通常可以做到。我正在认真地对待某些事情,希望有人可以对此有所了解。

我有一个WSDL,我正在连接并获得一个用于未来请求的sessionToken,一切都很好。

我现在尝试调用VmifCreateVisitor方法,根据SOAP UI,应该看起来如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:vmif="http://www.gallagher.co/security/commandcentre/vmifws" xmlns:web="http://www.gallagher.co/security/commandcentre/webservice">
   <soapenv:Header/>
   <soapenv:Body>
      <vmif:VmifCreateVisitor>
         <!--Optional:-->
         <vmif:sessionToken>
            <web:Value>?</web:Value>
         </vmif:sessionToken>
         <!--Optional:-->
         <vmif:vmConfigDivisionId>
            <web:Value>?</web:Value>
         </vmif:vmConfigDivisionId>
         <!--Optional:-->
         <vmif:visitor>
            <!--Optional:-->
            <vmif:DetailFields>
               <!--Zero or more repetitions:-->
               <web:PdfValue>
                  <!--Optional:-->
                  <web:IsUsedForNotification>?</web:IsUsedForNotification>
                  <web:Name>?</web:Name>
                  <web:Type>?</web:Type>
               </web:PdfValue>
            </vmif:DetailFields>
            <vmif:FirstName>?</vmif:FirstName>
            <vmif:LastName>?</vmif:LastName>
            <!--Optional:-->
            <vmif:DivisionId>
               <web:Value>?</web:Value>
            </vmif:DivisionId>
            <!--Optional:-->
            <vmif:Id>
               <web:Value>?</web:Value>
            </vmif:Id>
            <!--Optional:-->
            <vmif:UserCode>?</vmif:UserCode>
            <vmif:VisitorTypeIds>
               <!--Zero or more repetitions:-->
               <vmif:VmifVisitorTypeId>
                  <web:Value>?</web:Value>
               </vmif:VmifVisitorTypeId>
            </vmif:VisitorTypeIds>
         </vmif:visitor>
      </vmif:VmifCreateVisitor>
   </soapenv:Body>
</soapenv:Envelope>

如果我遗漏DetailFields部分,我可以创建访问者:

<vmif:DetailFields>
  <!--Zero or more repetitions:-->
  <web:PdfValue>
    <!--Optional:-->
    <web:IsUsedForNotification>?</web:IsUsedForNotification>
    <web:Name>?</web:Name>
    <web:Type>?</web:Type>
  </web:PdfValue>
</vmif:DetailFields>

但这不是我能做的事情,我需要在POST请求中发送一些个人详细信息。这是它变得奇怪的地方。当我发送以下SOAP DetailFields Params时,我得到&#34;无法创建抽象类&#34;

// ... (Truncated for Brevity)
$params->visitor->FirstName = $request->firstname;
$params->visitor->LastName = $request->lastname;

# ▼▼ Works if commented out. ▼▼
$mobile = new PdfValue();
$mobile->IsUsedForNotification = null;
$mobile->Name = 'Mobile Number';
$mobile->Type = 'Mobile';
$mobile->Value = $request->mobile;

$address = new PdfValue();
$address->IsUsedForNotification = null;
$address->Name = 'Address';
$address->Type = 'Address';
$address->Value = $request->address;

$params->visitor->DetailFields = [
    $address,
    $mobile
];
# ▲▲ Works if commented out. ▲▲

$visitorId = new VmifVisitorTypeId();
$visitorId->Value = $request->visitor_type_id;
$params->visitor->VisitorTypeIds = [
    $visitorId
];
// ... (Truncated for Brevity)

Generated PHP WSDL Class创建了以下PdfValue()类:

class PdfValue {
    public $IsUsedForNotification; // boolean
    public $Name; // string
    public $Type; // PdfType
}

但我注意到它缺少Value参数,与SOAP UI中的SOAP结构相同。 (将它添加到类没有区别)。

如果您有点好奇,这里是WSDL生成的VmifVisitor类:

class VmifVisitor {
    public $DivisionId; // VmifDivisionId
    public $Id; // VmifVisitorId
    public $UserCode; // string
    public $VisitorTypeIds; // ArrayOfVmifVisitorTypeId
}

如上所示 - 它缺少DetailFields参数,即使SOAP API文档清楚地显示了它的必要,(手动将它添加到类仍然没有帮助)

“实际”文档显示PdfValue的以下结构:

SOAP API Documentation for PdfValue

正如您所看到的,它清楚地将Value显示为object。我希望将它发送到对象中是什么意思?

完成后,这是Visitor对象的文档:

Visitor object API Documentation

所以我们可以看到它期待一个PdfValue的数组,我相信我正在发送。任何想法?

TL; DR 我得到&#34;无法创建抽象类&#34;当我在DetailFields中为VmifVisitorCreate方法发送一个PdfValue()数组时。 PdfValue的自动生成的php类缺少Value参数,而SOAP API Docs需要一个Value参数并说它应该是一个对象,将Value param添加到我的PdfValue类仍会产生相同的错误,这让我感到困惑。

1 个答案:

答案 0 :(得分:1)

我觉得很傻,这基本上归结为名称空间问题。由于我假设所有类型都在同一名称空间中,因此未找到Type。简单地改变:

$params->visitor->DetailFields = [
    $address,
    $mobile
];

$params->visitor->DetailFields = [
    new \SoapVar($address, SOAP_ENC_OBJECT, 'PdfGeneralValue', 'http://www.domain.co/security/namespacepath/webservice'),
    new \SoapVar($mobile, SOAP_ENC_OBJECT, 'PdfGeneralValue', 'http://www.domain.co/security/namespacepath/webservice'),
];

这使它可以工作。请注意,我还将type_name更改为PdfGeneralValue,这也是让它发挥作用的关键。谢谢大家。