PHP Soap 具有重复键的复杂参数

PHP Soap complex params with repeated keys

我需要生成以下内容XML

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.bloomberg.com/datalicense/dlws/ps/20071001">
    <SOAP-ENV:Body>
        <ns1:submitGetHistoryRequest>
            <ns1:headers>
                <ns1:daterange>
                    <ns1:period>
                        <ns1:start>2018-05-08</ns1:start>
                        <ns1:end>2018-05-08</ns1:end>
                    </ns1:period>
                </ns1:daterange>
            </ns1:headers>
            <ns1:fields>
                <ns1:field>PX_LAST</ns1:field>
            </ns1:fields>
            <ns1:instruments>
                <ns1:instrument>
                    <ns1:id>US0000000002</ns1:id>
                    <ns1:yellowkey>Equity</ns1:yellowkey>
                    <ns1:type>ISIN</ns1:type>
                </ns1:instrument>
                <ns1:instrument>
                    <ns1:id>US0000000001</ns1:id>
                    <ns1:yellowkey>Equity</ns1:yellowkey>
                    <ns1:type>ISIN</ns1:type>
                </ns1:instrument>
            </ns1:instruments>
        </ns1:submitGetHistoryRequest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我使用 PHP 7.1.17 和 SoapClient。

我无法将选项传递给 SoapClient,因为 instrument 键重复并且 PHP 的关联数组不能两次具有相同的键。我尝试构建对象并将 instrument 属性设置为 SoapVar,但它生成了不正确的 XML。这是代码和结果:

$options = new \stdClass();
$options->headers = new \stdClass();
$options->headers->daterange = new \stdClass();
$options->headers->daterange->period = new \stdClass();
$options->headers->daterange->period->start = '2018-05-08';
$options->headers->daterange->period->end = '2018-05-08';
$options->fields = new \stdClass();
$options->fields->field = 'PX_LAST';

//first instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000002';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';
$options->instruments[] = new \SoapVar(
    $instrument,
    SOAP_ENC_OBJECT,
    'stdClass',
    "http://soapinterop.org/xsd",
    "instrument"
);
//second instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000001';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';
$options->instruments[] = new \SoapVar(
    $instrument,
    SOAP_ENC_OBJECT,
    'stdClass',
    "http://soapinterop.org/xsd",
    "instrument"
);

<ns1:instruments/> 在结果 XML:

中保持为空
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://services.bloomberg.com/datalicense/dlws/ps/20071001">
    <SOAP-ENV:Body>
        <ns1:submitGetHistoryRequest>
            <ns1:headers>
                <ns1:daterange>
                    <ns1:period>
                        <ns1:start>2018-05-08</ns1:start>
                        <ns1:end>2018-05-08</ns1:end>
                    </ns1:period>
                </ns1:daterange>
            </ns1:headers>
            <ns1:fields>
                <ns1:field>PX_LAST</ns1:field>
            </ns1:fields>
            <ns1:instruments/>
        </ns1:submitGetHistoryRequest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

如何将选项传递给 SoapClient,以使用重复的 instrument 键生成 XML?

我解决了这个问题。事实证明,当您将有序数组(非关联数组)作为对象的 属性 传递时,使用该 属性 的名称生成的 XML 节点数量与数组中的元素数量一样多。因此,我没有构建 SoapVar 对象并将它们放入 instruments[] 数组,而是将仪器数组分配给 instruments 作为 instrument 属性:

$options->instruments = new \stdClass();

//first instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000002';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';

$options->instruments->instrument[] = $instrument;

//second instrument
$instrument = new \stdClass();
$instrument->id = 'US0000000001';
$instrument->type = 'ISIN';
$instrument->yellowkey = 'Equity';

$options->instruments->instrument[] = $instrument;

我在 foreach 循环中构建乐器。顺便说一句,将数组转换为对象而不是构建 stdClass 也可以正常工作:

$options->instruments->instrument[] = (object)[
    'id' => 'US0000000001',
    'type' => 'ISIN',
    'yellowkey' => 'Equity'
]