SoapClient 没有生成正确的请求
SoapClient does not generate correct Request
我有 SOAP 端点,我想使用 PHP 的 \SoapClient class 发送请求。问题是即使 "senderAddress" 属性有例如。 "name"、"nameDetail"、"type" 属性(其中一些是文档需要的),生成的 XML 请求不包含它们。它 accepts/generates 的唯一属性是 "id" 属性。
同样的问题也出现在发货对象的另一部分- f.ex。 Pickup 部分允许我只设置 "date" 属性,所有其他属性都是 skipped/ignored.
我在下面准备了一些虚拟代码,没有数据对象,只是一个简单的数组:
<?php
$soapClient = new \SoapClient("https://capi.dpdportal.sk/apix/shipment/?wsdl", [
'trace' => 1
]);
$headers = array();
$dpdSecurity = new \stdClass();
$token = new \stdClass();
$token->ClientKey = "topsecretkey";
$token->Email = "topsecretmail";
$dpdSecurity->SecurityToken = $token;
$headers["auth"] = new \SoapHeader('http://www.dpdportal.sk/XMLSchema/DPDSecurity/v2', 'DPDSecurity', $dpdSecurity);
$soapClient->__setSoapHeaders($headers);
$shipment = [
"reference" => "123",
"delisId" => "123",
"addressSender" => [
"type" => "b2c", // this attribute is missing in the Request
"id" => 41656415651,
"nameDetail" => "test", // this attribute is missing in the Request
],
"addressRecipient" => "123",
"product" => 9,
"parcels" => [],
"pickup" => null,
];
$params = [
'shipment' => $shipment,
];
try {
$response = $soapClient->CreateV1($params);
echo '==' . PHP_EOL;
var_dump($response);
} catch (\Exception $e) {
echo $e->getMessage();
}
生成的请求:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.dpdportal.sk/XMLSchema/SHIPMENT/v1" xmlns:ns2="http://www.dpdportal.sk/XMLSchema/DPDSecurity/v2">
<SOAP-ENV:Header>
<ns2:DPDSecurity>
<ns2:SecurityToken>
<ns2:ClientKey>topsecretkey</ns2:ClientKey>
<ns2:Email>topsecretmail</ns2:Email>
</ns2:SecurityToken>
</ns2:DPDSecurity>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:CreateRequest>
<ns1:shipment>
<ns1:reference>123</ns1:reference>
<ns1:delisId>123</ns1:delisId>
<ns1:product>9</ns1:product>
<ns1:pickup />
<ns1:addressSender>
<ns1:id>41656415651</ns1:id>
</ns1:addressSender>
<ns1:addressRecipient />
<ns1:parcels />
</ns1:shipment>
</ns1:CreateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Shipment v1 schema 表示 addressSender
元素是 SHIPMENT:addressEnvelope
类型,定义如下:
<xsd:complexType name="addressEnvelope">
<xsd:annotation>
<xsd:documentation>Address envelope</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:sequence>
<xsd:element name="id" type="SHIPMENT:idType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Address ID</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="type" type="SHIPMENT:addresstypeType" minOccurs="0" />
<xsd:element name="name" type="SHIPMENT:nameType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Contact person</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="nameDetail" type="SHIPMENT:nameType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Contact person (detail)</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="street" type="SHIPMENT:streetType" minOccurs="0" />
<xsd:element name="streetDetail" type="SHIPMENT:streetType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Street (detail)</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="houseNumber" type="SHIPMENT:houseNumberType" minOccurs="0" />
<xsd:element name="zip" type="SHIPMENT:zipType" minOccurs="0" />
<xsd:element name="country" type="SHIPMENT:countryType" minOccurs="0" />
<xsd:element name="city" type="SHIPMENT:cityType" minOccurs="0" />
<xsd:element name="phone" type="SHIPMENT:phoneType" minOccurs="0" />
<xsd:element name="email" type="SHIPMENT:emailType" minOccurs="0" />
<xsd:element name="reference" type="SHIPMENT:referenceType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Reference for address (e.g. specific code of client)</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="note" type="SHIPMENT:noteType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Free note related to address</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="ico" type="SHIPMENT:icoType" minOccurs="0" />
<xsd:element name="vatId" type="SHIPMENT:vatIdType" minOccurs="0" />
<xsd:element name="vatId2" type="SHIPMENT:vatId2Type" minOccurs="0" />
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
由于addressEnvelope
是一个选择项,您只能定义其中一个序列。由于您的数据包含 id
,SoapClient 使用第一个序列。
更新
经过进一步测试,我可以得出结论 SoapClient
永远不会选择第二个序列,因为第一个序列只有一个可选的 id
元素,这导致您提供的任何数据都是有效的。
我能够强制 SoapClient
选择第二个序列的唯一方法是将 id
元素的 minOccurs
值更改为 1
。
为此,您必须下载 WSDL 文件和 Shipment v1 架构,在本地托管它们,并更新 URL。
我有 SOAP 端点,我想使用 PHP 的 \SoapClient class 发送请求。问题是即使 "senderAddress" 属性有例如。 "name"、"nameDetail"、"type" 属性(其中一些是文档需要的),生成的 XML 请求不包含它们。它 accepts/generates 的唯一属性是 "id" 属性。
同样的问题也出现在发货对象的另一部分- f.ex。 Pickup 部分允许我只设置 "date" 属性,所有其他属性都是 skipped/ignored.
我在下面准备了一些虚拟代码,没有数据对象,只是一个简单的数组:
<?php
$soapClient = new \SoapClient("https://capi.dpdportal.sk/apix/shipment/?wsdl", [
'trace' => 1
]);
$headers = array();
$dpdSecurity = new \stdClass();
$token = new \stdClass();
$token->ClientKey = "topsecretkey";
$token->Email = "topsecretmail";
$dpdSecurity->SecurityToken = $token;
$headers["auth"] = new \SoapHeader('http://www.dpdportal.sk/XMLSchema/DPDSecurity/v2', 'DPDSecurity', $dpdSecurity);
$soapClient->__setSoapHeaders($headers);
$shipment = [
"reference" => "123",
"delisId" => "123",
"addressSender" => [
"type" => "b2c", // this attribute is missing in the Request
"id" => 41656415651,
"nameDetail" => "test", // this attribute is missing in the Request
],
"addressRecipient" => "123",
"product" => 9,
"parcels" => [],
"pickup" => null,
];
$params = [
'shipment' => $shipment,
];
try {
$response = $soapClient->CreateV1($params);
echo '==' . PHP_EOL;
var_dump($response);
} catch (\Exception $e) {
echo $e->getMessage();
}
生成的请求:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.dpdportal.sk/XMLSchema/SHIPMENT/v1" xmlns:ns2="http://www.dpdportal.sk/XMLSchema/DPDSecurity/v2">
<SOAP-ENV:Header>
<ns2:DPDSecurity>
<ns2:SecurityToken>
<ns2:ClientKey>topsecretkey</ns2:ClientKey>
<ns2:Email>topsecretmail</ns2:Email>
</ns2:SecurityToken>
</ns2:DPDSecurity>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:CreateRequest>
<ns1:shipment>
<ns1:reference>123</ns1:reference>
<ns1:delisId>123</ns1:delisId>
<ns1:product>9</ns1:product>
<ns1:pickup />
<ns1:addressSender>
<ns1:id>41656415651</ns1:id>
</ns1:addressSender>
<ns1:addressRecipient />
<ns1:parcels />
</ns1:shipment>
</ns1:CreateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Shipment v1 schema 表示 addressSender
元素是 SHIPMENT:addressEnvelope
类型,定义如下:
<xsd:complexType name="addressEnvelope">
<xsd:annotation>
<xsd:documentation>Address envelope</xsd:documentation>
</xsd:annotation>
<xsd:choice>
<xsd:sequence>
<xsd:element name="id" type="SHIPMENT:idType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Address ID</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="type" type="SHIPMENT:addresstypeType" minOccurs="0" />
<xsd:element name="name" type="SHIPMENT:nameType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Contact person</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="nameDetail" type="SHIPMENT:nameType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Contact person (detail)</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="street" type="SHIPMENT:streetType" minOccurs="0" />
<xsd:element name="streetDetail" type="SHIPMENT:streetType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Street (detail)</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="houseNumber" type="SHIPMENT:houseNumberType" minOccurs="0" />
<xsd:element name="zip" type="SHIPMENT:zipType" minOccurs="0" />
<xsd:element name="country" type="SHIPMENT:countryType" minOccurs="0" />
<xsd:element name="city" type="SHIPMENT:cityType" minOccurs="0" />
<xsd:element name="phone" type="SHIPMENT:phoneType" minOccurs="0" />
<xsd:element name="email" type="SHIPMENT:emailType" minOccurs="0" />
<xsd:element name="reference" type="SHIPMENT:referenceType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Reference for address (e.g. specific code of client)</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="note" type="SHIPMENT:noteType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>Free note related to address</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="ico" type="SHIPMENT:icoType" minOccurs="0" />
<xsd:element name="vatId" type="SHIPMENT:vatIdType" minOccurs="0" />
<xsd:element name="vatId2" type="SHIPMENT:vatId2Type" minOccurs="0" />
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
由于addressEnvelope
是一个选择项,您只能定义其中一个序列。由于您的数据包含 id
,SoapClient 使用第一个序列。
更新
经过进一步测试,我可以得出结论 SoapClient
永远不会选择第二个序列,因为第一个序列只有一个可选的 id
元素,这导致您提供的任何数据都是有效的。
我能够强制 SoapClient
选择第二个序列的唯一方法是将 id
元素的 minOccurs
值更改为 1
。
为此,您必须下载 WSDL 文件和 Shipment v1 架构,在本地托管它们,并更新 URL。