douhao7889 2018-08-09 15:27
浏览 32
已采纳

将XML嵌入SOAP / PHP编码低于和高于符号

We have an WSDL that contains the following and make a call using the standard SOAP Client of PHP:

<element name="doSomething">
    <complexType>
        <sequence>
            <element name="Payload" nillable="true" type="xsd:string"/>
            <element name="Username" type="string"/>
            <element name="service" type="string"/>
            <element name="Password" type="string"/>
        </sequence>
    </complexType>
</element>

The Payload is essentially XML data, which looks for example like this

<code>1</code>

Now the request of the SOAP client, dumped via echo $client->__getLastRequest(); looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="pa/WebshopService"><SOAP-ENV:Body><ns1:doSomething><ns1:Payload>&lt;code&gt;
1
&lt;/code&gt;
</ns1:pcRequest><ns1:Username>bar</ns1:Username><ns1:service>bar</ns1:service><ns1:Password>bar</ns1:Password></ns1:doSomething></SOAP-ENV:Body></SOAP-ENV:Envelope>

which, I believe makes sense, as the < and > should be encoded.

The counterpart seems to expect something like this:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="pa/WebshopService"><SOAP-ENV:Body><ns1:doSomething><ns1:Payload><code>
1
</code>
</ns1:pcRequest><ns1:Username>bar</ns1:Username><ns1:service>bar</ns1:service><ns1:Password>bar</ns1:Password></ns1:doSomething></SOAP-ENV:Body></SOAP-ENV:Envelope>
  • How can I send such using the PHP SoapClient?
  • Is the WSDL even valid in this case?
  • 写回答

1条回答 默认 最新

  • douzhan1994 2018-08-10 08:42
    关注

    Well, the complex type doSomething says, that the property Payload is of type string. Consequently the encoded string of the xml content should be right. If the provider side expects the content not encoded, the property Payload would be another complex type. So in this case the wsdl is not valid, if it 's true, that the provider side really wants an element and not an encoded string.

    Anyway, there 's a solution you can handle this with PHP. Just handle Payload not as a string. Instead make a complex type out of it.

    class DoSomething()
    {
        protected $Payload;
    
        protected $Username;
    
        protected $Service;
    
        protected $Password;
    
        public function getPayload() : ?\SoapVar        {
            return $this->Payload;
        }
    
        public function setPayload(\SoapVar $payload) : DoSomething
        {
            $this->Payload = $payload;
            return $this;
        }
    
        ...
    
        public function encode() : \SoapVar
        {
            return new \SoapVar(
                $this,
                SOAP_ENC_OBJECT,
                null,
                null,
                'doSomething',
                'http://www.example.com/namespace'
            );
        }
    }
    

    Above you see the complex type doSomething as a PHP class. You also see an examplary getter and setter method. The get method returns null or a \SoapVar instance. The setter method takes a \SoapVar instance.

    For your purpose you 'll need another PHP class for the Payload property, which contains the code property.

    class Payload
    {
        protected $Code;
    
        public function getCode() : ?\SoapVar
        {
            return $this->Code;
        }
    
        public function setCode(\SoapVar $code) : Payload
        {
            $this->Code = $code;
            return $this;
        }
    
        public function encode() : \SoapVar
        {
            return new \SoapVar
            {
                $this,
                SOAP_ENC_OBJECT,
                null,
                null,
                'Payload',
                'http://www.example.com/namespace'
            }
        }
    }
    

    Now just put all together ...

    $code = new \SoapVar(1, XSD_INT, null, null, 'code');
    
    $payload = (new Payload())
        ->setCode($code)
        ->encode();
    
    $doSomething = (new DoSomething())
        ->setPayload($payload)
        ->setUsername(...)
        ->setService(...)
        ->setPassword(...)
        ->encode();
    
    $result = $client->doSomething($doSomething);
    

    Now your request should look like ...

    <ns1:doSomething>
        <ns1:Payload>
            <code>1</code>
        </ns1:Payload>
        <ns1:Username>...</ns1:Username>
        <ns1:Service>...</ns1:Service>
        <ns1:Password>...</ns1:Password>
    </ns1:doSomething>
    

    Hope that helped you.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)
  • ¥15 机器人轨迹规划相关问题
  • ¥15 word样式右侧翻页键消失