在使用PHP向Soap Server提交数据时删除<return>标记

时间:2016-04-14 11:10:03

标签: php soap

实际结果:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/" 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:PerformTransactionArgumentsResponse>
            <return xsi:type="SOAP-ENC:Struct">
                <errorMsg xsi:type="xsd:string">Ok</errorMsg>
                <status xsi:type="xsd:string">0</status>
                <timeStamp xsi:type="xsd:string">2011-04-26T19:13:55.421875+05:00</timeStamp>
            </return>
        </ns1:PerformTransactionArgumentsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

预期结果没有<return xsi:type="SOAP-ENC:Struct"></return>标记。

我是第一次这样做,实际上我对Soap Server几乎一无所知,你能告诉我,我该如何删除返回标签?

这是服务器端的代码:

class PerformTransactionArgumentsResponse {
    public $errorMsg = "Ok";
    public $status = "0";
    public $timeStamp = "2011-04-26T19:13:55.421875+05:00";
}


class MyAPI {
    function PerformTransactionArguments() {
        return new PerformTransactionArgumentsResponse;
    }
}

$options=array('uri'=>'localhost/');
$server = new SoapServer(NULL,$options);
$server->setClass('MyAPI');
$server->handle();

1 个答案:

答案 0 :(得分:1)

为了做你想做的事,你必须制作一个WSDL文档并将它传递给服务器和客户端。让我们开始创建一个名为wsdl-pruebas.wsdl的WSDL文档,其中包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="TransactionArguments"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xs="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:ns1="http://localhost/pruebas"
             targetNamespace="http://localhost/pruebas">
    <types>
        <xs:schema targetNamespace="http://localhost/pruebas">
            <xs:element name="PerformTransactionArgumentsResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="errorMsg" type="xs:string"/>
                        <xs:element name="status" type="xs:string"/>
                        <xs:element name="timeStamp" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </types>

    <message name="PerformTransactionArgumentsRequest"/>
    <message name="PerformTransactionArgumentsResponse">
        <part name="return" element="ns1:PerformTransactionArgumentsResponse"/>
    </message>

    <portType name="PerformTransactionArgumentsPortType">
        <operation name="PerformTransactionArguments">
            <input message="PerformTransactionArgumentsRequest"/>
            <output message="PerformTransactionArgumentsResponse"/>
        </operation>
    </portType>

    <binding name="PerformTransactionArgumentsBinding" type="PerformTransactionArgumentsPortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="PerformTransactionArguments">
            <soap:operation soapAction=""/>
            <input/>
            <output>
                <soap:body use="encoded" namespace="http://localhost/pruebas" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
            </output>
        </operation>
    </binding>

    <service name="PerformTransactionArgumentsResponseService">
        <documentation>Returns an error message.</documentation>
        <port name="PerformTransactionArgumentsPort" binding="PerformTransactionArgumentsBinding">
            <soap:address location="http://localhost/pruebas/soap-server.php"/>
        </port>
    </service>
</definitions>

这个定义似乎势不可挡,但是一旦你逐节分析它就很简单了,我们将在下面进行分析。首先,我们在此定义响应的类型:

<types>
    <xs:schema targetNamespace="http://localhost/pruebas">
        <xs:element name="PerformTransactionArgumentsResponse">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="errorMsg" type="xs:string"/>
                    <xs:element name="status" type="xs:string"/>
                    <xs:element name="timeStamp" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
</types>

正如您所看到的,它与您的班级相同。我们稍后会用它。接下来,我们定义请求和响应消息:

<message name="PerformTransactionArgumentsRequest"/>
<message name="PerformTransactionArgumentsResponse">
    <part name="return" element="ns1:PerformTransactionArgumentsResponse"/>
</message>

我们正在定义一个空请求,但是您的类的类型的响应。记下name属性,其值为return。这是您目前在服务器响应中看到的内容。接下来,我们为SOAP服务器的操作定义“接口”:

<portType name="PerformTransactionArgumentsPortType">
    <operation name="PerformTransactionArguments">
        <input message="PerformTransactionArgumentsRequest"/>
        <output message="PerformTransactionArgumentsResponse"/>
    </operation>
</portType>

inputoutput只是指向上述消息。接下来,我们定义portType的“细节”:

<binding name="PerformTransactionArgumentsBinding" type="PerformTransactionArgumentsPortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="PerformTransactionArguments">
        <soap:operation soapAction=""/>
        <input/>
        <output>
            <soap:body use="encoded" namespace="http://localhost/pruebas" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
        </output>
    </operation>
</binding>

这里 soap:binding 告诉我们它正在使用SOAP 1.1。

最后,我们通过服务部分公开绑定:

<service name="PerformTransactionArgumentsResponseService">
    <documentation>Returns an error message.</documentation>
    <port name="PerformTransactionArgumentsPort" binding="PerformTransactionArgumentsBinding">
        <soap:address location="http://localhost/pruebas/soap-server.php"/>
    </port>
</service>

soap:地址指向soap服务器脚本的网址(在此示例中为 http://localhost/pruebas/soap-server.php )。

在定义WSDL文档之后,我们对soap服务器脚本进行编码(在此示例中将命名为soap-server.php):

class PerformTransactionArgumentsResponse {
    public $errorMsg = "Ok";
    public $status = "0";
    public $timeStamp = "2011-04-26T19:13:55.421875+05:00";
}


class MyAPI {
    function PerformTransactionArguments() {
        return new PerformTransactionArgumentsResponse;
    }
}

$options = [
    'soap_version' => SOAP_1_1,
    'cache_wsdl' => WSDL_CACHE_NONE
];

$server = new SoapServer('http://localhost/pruebas/soap-pruebas.wsdl', $options);
$server->setClass('MyAPI');
$server->handle();

这次我们提供WSDL文档的URL并修改$options数组。

要查看所有这些操作,我们创建了一个SOAP客户端脚本(在此示例中为soap-client.php):

try {
    $options = [
        'soap_version' => SOAP_1_1,
        'trace'=>1
    ];

    $client = new SOAPClient('http://localhost/pruebas/soap-pruebas.wsdl', $options);

    $response = $client->PerformTransactionArguments();

    header('Content-type:text/xml');
    echo $client->__getLastResponse();
}
catch (SoapFault $e) {
    echo $e;
}

同样,我们指定WSDL文档的URL。运行客户端脚本将给出:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="http://localhost/pruebas" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:PerformTransactionArgumentsResponse xsi:type="ns1:PerformTransactionArgumentsResponse">
            <errorMsg xsi:type="xsd:string">Ok</errorMsg>
            <status xsi:type="xsd:string">0</status>
            <timeStamp xsi:type="xsd:string">2011-04-26T19:13:55.421875+05:00</timeStamp>
        </ns1:PerformTransactionArgumentsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

与soap服务器脚本生成的响应有什么不同?

soap:binding 定义中,如果我们将style sttribute的值从document修改为rpc

<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

我们会得到这样的答复:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/pruebas" 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:PerformTransactionArgumentsResponse>
            <return xsi:type="ns1:PerformTransactionArgumentsResponse">
                <errorMsg xsi:type="xsd:string">Ok</errorMsg>
                <status xsi:type="xsd:string">0</status>
                <timeStamp xsi:type="xsd:string">2011-04-26T19:13:55.421875+05:00</timeStamp>
            </return>
        </ns1:PerformTransactionArgumentsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

您目前收到的回复是什么。

修改 最后,如果我们更改 soap:body 行:

<soap:body use="encoded" namespace="http://localhost/pruebas" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

到此:

<soap:body use="literal"/>

回复将是:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/pruebas">
    <SOAP-ENV:Body>
        <ns1:PerformTransactionArgumentsResponse>
            <errorMsg>Ok</errorMsg>
            <status>0</status>
            <timeStamp>2011-04-26T19:13:55.421875+05:00</timeStamp>
        </ns1:PerformTransactionArgumentsResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

注意:为此,我假设脚本和WDSL位于http://localhost/pruebas/