首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在XML中,关联数组键在传递给SoapClient时变为param。

在XML中,关联数组键在传递给SoapClient时变为param。
EN

Stack Overflow用户
提问于 2020-11-02 14:05:19
回答 2查看 553关注 0票数 2

我有一个关联数组:

代码语言:javascript
运行
复制
$params = [
  'trid' => null,
  'merchantCode' => null,
  'paymentMethod' => null,
  'returnUrl' => site_url(null),
  'notificationUrl' => site_url(null),
  'language' => 'null',
  'currency' => 'null',
  'isTestMode' => false,
  'productsXml' => null,
  'needInvoice' => true,

(虚无持有现实中的实际价值)

当我检查__getLastRequest时,我会完全丢失生成的XML中的键。

SoapClient,

代码语言:javascript
运行
复制
    $soap = new SoapClient(null, $options);
    $soap->__soapCall('Request', $params);
    $request = $soap->__getLastRequest();

请注意,我与端点有一个非WSDL连接。

生成的XML将具有一个<param[keyNum] xsi:type="xsd:typeOfVariable">字段值,而不是来自关联数组(例如<trid> )的实际键值。

代码语言:javascript
运行
复制
<SOAP-ENV:Body><ns1:Request><param0 xsi:type="xsd:string">null</param0><param1 xsi:type="xsd:string">null</param1></Request>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-06 22:09:46

与PHP手册中的他说相反,arguments似乎从未被解释为一个关联数组。

如果我们尝试这个简单的测试:

代码语言:javascript
运行
复制
<?php
$options = ['location'=>'http://localhost/unknown', 'uri'=>'test', 'trace'=>true];
$soap = new SoapClient(null, $options);
try
{
    $soap->__soapCall('Request', ['foo'=>1, 'bar'=>2]);
}
catch(SoapFault $e)
{
    header('Content-type: text/xml');
    echo $soap->__getLastRequest();
}
?>

我们得到:

代码语言:javascript
运行
复制
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:Request>
            <param0 xsi:type="xsd:int">1</param0>
            <param1 xsi:type="xsd:int">2</param1>
        </ns1:Request>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我们看到参数名被忽略了。

现在,如果我们尝试另一个答案所建议的(将数组包装在另一个数组中):

代码语言:javascript
运行
复制
<?php
$options = ['location'=>'http://localhost/unknown', 'uri'=>'test', 'trace'=>true];
$soap = new SoapClient(null, $options);
try
{
    $soap->__soapCall('Request', [['foo'=>1, 'bar'=>2]]);
}
catch(SoapFault $e)
{
    header('Content-type: text/xml');
    echo $soap->__getLastRequest();
}
?>

我们得到:

代码语言:javascript
运行
复制
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:Request>
            <param0 xsi:type="ns2:Map">
                <item>
                    <key xsi:type="xsd:string">foo</key>
                    <value xsi:type="xsd:int">1</value>
                </item>
                <item>
                    <key xsi:type="xsd:string">bar</key>
                    <value xsi:type="xsd:int">2</value>
                </item>
            </param0>
        </ns1:Request>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我们看到有一个参数的类型是Map。这不是我们想要的。

解决方案是使用SoapParam类:

代码语言:javascript
运行
复制
<?php
$options = ['location'=>'http://localhost/unknown', 'uri'=>'test', 'trace'=>true];
$soap = new SoapClient(null, $options);
try
{
    $soap->__soapCall('Request', [new SoapParam(1, 'foo'), new SoapParam(2, 'bar')]);
}
catch(SoapFault $e)
{
    header('Content-type: text/xml');
    echo $soap->__getLastRequest();
}
?>

现在我们得到了我们想要的:

代码语言:javascript
运行
复制
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:Request>
            <foo xsi:type="xsd:int">1</foo>
            <bar xsi:type="xsd:int">2</bar>
        </ns1:Request>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

请注意,您可以轻松地将关联数组转换为SOAP参数,如下所示:

代码语言:javascript
运行
复制
function getSoapParams($params)
{
    $a = [];
    foreach($params as $name=>$value)
        $a[] = new SoapParam($value, $name);
    return $a;
}
票数 2
EN

Stack Overflow用户

发布于 2020-11-06 14:23:39

根据文件中的说明

如果要调用__soapCall,则必须将参数包装在另一个数组中,如下所示:

代码语言:javascript
运行
复制
$params = array('username'=>'name', 'password'=>'secret');
<?php
$client->__soapCall('login', array($params));
?>

以下一行:

$soap->__soapCall('Request', $params);

应:

$soap->__soapCall('Request', [$params]);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64647054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档