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 fluent的在模拟压强时使用希望得到一些建议
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退