【问题标题】:PHP - Set a Namespace in SoapClientPHP - 在 SoapClient 中设置命名空间
【发布时间】:2023-03-29 16:46:01
【问题描述】:

我遇到了 SOAP 调用问题,我认为它与命名空间有关。我从要发送到的服务器收到不正确的响应,这似乎是由于不正确的 SOAP 信封和命名空间。

152     protected function callWithSOAP($xml) {
153         
154         try {
155             $soapClient = new SoapClient($this->mercuryWSDL, array('trace'=>1));
156         } catch (Exception $e) {
157             throw new Exception($e->getMessage());
158         }
159         
160         $message = array(
161             'tran'=> $xml,
162             'pw'=> $this->mercuryPassword
163         );      
164         
165         // Make SOAP Call
166         try {
167             $request = $soapClient->CreditTransaction($message);
168         } catch (Exception $e) { 
169             throw new Exception($e->getMessage());
170         }
171 
172         $res = $soapClient->__getLastRequest();
173         return $res;
174 
175         return $request;
176     }

我在方法签名中输入的 XML 很好,我已经确认这与服务器所期望的相同,特别是有问题的肥皂请求。

这是我使用 SoapClient 发送的 SOAP 请求:

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.mercurypay.com">
    <SOAP-ENV:Body>
        <ns1:CreditTransaction>
            <ns1:tran>
            <?xml version="1.0"?>
            <TStream>
                <Transaction>
                    <MerchantID>******</MerchantID>
                    <TranType>Credit</TranType>
                    <TranCode>FSASale</TranCode>
                    <InvoiceNo>12</InvoiceNo>
                    <RefNo>12</RefNo>
                    <Account>
                        <AcctNo>*******</AcctNo>
                        <ExpDate>****</ExpDate>
                    </Account>
                    <Amount>
                        <Purchase>25</Purchase>
                        <FSAPrescription>25</FSAPrescription>
                    </Amount>
                </Transaction>
            </TStream>
        </ns1:tran>
        <ns1:pw>xyz</ns1:pw>
    </ns1:CreditTransaction>
</SOAP-ENV:Body>

但这是它实际所期望的......我该如何匹配这个:

<soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mer="http://www.mercurypay.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<mer:CreditTransaction>
<mer:tran>
<?xml version="1.0"?>
<TStream>
  <Transaction>
<MerchantID>******</MerchantID>
<TranType>Credit</TranType>
<TranCode>FSASale</TranCode>
<InvoiceNo>1</InvoiceNo>
<RefNo>1</RefNo>
<Account>
  <AcctNo>************</AcctNo>
  <ExpDate>****</ExpDate>
</Account>
<Amount>
  <Purchase>63.54</Purchase>
  <FSAPrescription>63.54</FSAPrescription>
</Amount>
</Transaction>
</TStream>
</mer:tran>
<mer:pw>xyz</mer:pw>
</mer:CreditTransaction>
</soapenv:Body>
</soapenv:Envelope>

你会注意到到处都是“mer:”。我相信这是我需要从服务器获得正确响应的原因。请帮帮我,这应该明天出去测试,我们才意识到对此的反应非常不一致。

感谢您提供的任何帮助,非常感谢。

【问题讨论】:

    标签: php xml soap soap-client


    【解决方案1】:

    &lt;mer: 命名空间前缀在文档中定义(在 &lt;soapenv:Envelope ... xmlns:mer="http://www.mercurypay.com" ... &gt; 中),但是不允许在文档开头以外的位置使用 the XML declaration &lt;?xml version="1.0"?&gt;

    这是您违反的 XML 中的一个具体规则,您不能指望这会像 SOAP 基于 XML 一样起作用。

    您设置'tran'=&gt; $xml 的方式,尤其是$message 上下文中CreditTransaction($message) 中的$xml 似乎在这里是错误的。以正确的格式将数据放入$xml,以便正确传递(您的应用程序的那部分被隐藏起来,就像隐藏了 WSDL 的源一样,因此无法提供进一步的信息或提示)。

    【讨论】:

    • 问题是双重 声明。感谢您注意到这一点,我没有意识到 simplexml 正在添加它自己的并且肥皂调用没有删除它。有道理,谢谢。
    • 如果你想用 simplexml 防止这种情况,这很棘手,因为不可能有一个选项左右:eval.in/18017 - 我想我也曾在一个或另一个答案中发布过这个,但现在有点懒得去搜索了。也许部分在这里:stackoverflow.com/a/14831397/367456 - 这个变体使用与 explode() 不同的字符串函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多