3

一个关于PHP的SoapClient和SoapServer,WSDL模式的问题。

比方说,我需要为 XML 的某个部分创建一个摘要,其中包含其中的数据。使用 SoapClient 很容易。我从类中重载__doRequest()方法SoapClient,对某些元素进行散列并将其作为元素附加<Hash></Hash><SOAP-ENV:Header/>. 然后我将生成的 XML 发送到 SOAPServer 调用parent::__doRequest()

我需要对响应 XML 做同样的事情。在服务器方面,我遇到了困难。似乎服务器只能将数据作为嵌套数组或对象发送,并且以某种方式插入到客户端的响应 XML 中。我尝试发送带有SoapServer' 响应的 XML,然后它返回空 XML。

我真的需要在服务器端解析和修改 XML(制作哈希、数字签名等),但到目前为止,无论我在哪里搜索,我都没有找到答案,所以我真的很感谢你的帮助。谢谢。

4

1 回答 1

0

您必须获得一个没有 XML 声明的 XML 字符串,并使用 SoapVar 对其进行解析。
有关详细信息,请参阅how-return-custom-xml-response-in-soapserver-response

简而言之,就是这样。
您从输入和需要放入其中的任何其他内容构造一个 DOMDocument。XSLT是解析和更改 XML 的好方法(有关如何在 php 中使用 xslt 的简单示例,请再次参见上面的链接)。
然后DOMNodeDOMDocument您希望返回的节点中选择,并saveXML使用此节点作为参数应用。这会将所需的 XML 保存为没有声明的字符串。没有参数的普通saveXML()会将根节点保存为包含声明的字符串。因此:

$nodes = $dom -> getElementsByTagName ('chooseTheElementYouWishToReturn');
$node = $nodes -> item(0);

$result = new SoapVar ($dom -> saveXML($node), XSD_ANYXML);
return ($result);

当您希望返回根元素时,这当然也适用:

$result = new SoapVar ($dom -> saveXML($dom -> documentElement), XSD_ANYXML);
return ($result);

添加

我注意到您希望在 SOAP 标头而不是正文中添加一些内容。
这也有点棘手,但可以实现 - 我希望以下内容能满足您的需求。

首先,添加头部细节只能在函数脚本内完成,然后函数必须将服务器变量声明为全局变量,以便引用全局(函数外部)声明的变量,如下所示:

<?php   
    class mySOAPclass {
        function xxx ($arg) {
            global $server;

            // your code for the header part
            // example
            $auth = array();
            $auth['UserName'] = 'user';
            $auth['Password'] = 'pw';
            $header = new SoapVar ($auth, SOAP_ENC_OBJECT);
            // end example

            $header = new SoapHeader ('http://schemas.xmlsoap.org/soap/header/', 'credentials', $header, false);
            $server -> addSoapHeader ($header);

            // your code for the body part, assuming it results in a DOM $dom

            $result = new SoapVar ($dom -> saveXML($dom -> documentElement), XSD_ANYXML);

            return ($result);
        }

    ini_set( "soap.wsdl_cache_enabled", "0");
    $server = new SoapServer ("yourOwn.wsdl");
    $server -> setClass ('mySOAPclass');
    $server -> setObject (new mySOAPclass());
    $server -> handle();
?>

请注意,需要SoapVar先从数组中构造 a ;如果将数组直接提供给标题,则会得到丑陋的项目/键和项目/值节点。

以上导致以下返回结构:

<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://schemas.xmlsoap.org/soap/header/">
    <SOAP-ENV:Header>
        <ns1:credentials>
            <UserName>user</UserName>
            <Password>pw</Password>
        </ns1:credentials>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        ...
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
于 2012-10-06T11:27:33.337 回答