我是第一个承认我很少使用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
的以下结构:
正如您所看到的,它清楚地将Value
显示为object
。我希望将它发送到对象中是什么意思?
完成后,这是Visitor
对象的文档:
所以我们可以看到它期待一个PdfValue
的数组,我相信我正在发送。任何想法?
TL; DR 我得到&#34;无法创建抽象类&#34;当我在DetailFields中为VmifVisitorCreate方法发送一个PdfValue()数组时。 PdfValue的自动生成的php类缺少Value参数,而SOAP API Docs需要一个Value参数并说它应该是一个对象,将Value param添加到我的PdfValue类仍会产生相同的错误,这让我感到困惑。
答案 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
,这也是让它发挥作用的关键。谢谢大家。