3

PHP の SoapClient と SoapServer、WSDL モードについての質問です。

たとえば、データを含む XML の特定の部分のダイジェストを作成する必要があります。SoapClient を使えば簡単です。__doRequest()class からメソッドをオーバーロードし、特定の要素のハッシュを作成し、それを内SoapClientの要素としてアタッチします。次に、結果の XML を SOAPServer 呼び出し元に送信します。<Hash></Hash><SOAP-ENV:Header/>parent::__doRequest()

応答 XML についても同じことを行う必要があります。サーバー側では問題があります。サーバーはネストされた配列またはオブジェクトとしてのみデータを送信できるようで、クライアント側の応答 XML に何らかの形で挿入されます。の応答でXML を送信しようとしSoapServerましたが、空の XML が返されます。

サーバー側でXMLを解析して変更する必要があります(ハッシュ、デジタル署名などを作成する)が、これまでのところ、どこを検索してもその方法が見つからないので、助けていただければ幸いです。ありがとう。

4

1 に答える 1

0

You will have to get an XML string without XML declaration and parse that with SoapVar.
See how-return-custom-xml-response-in-soapserver-response for details.

In short, it comes to this.
You construct a DOMDocument from your input and any other stuff you need to put into it. XSLT is a nice way to parse and change XML (see above link again for a simple example on how to use xslt in php).
Then you select the DOMNode from the DOMDocument you wish to return, and apply saveXML with this node as parameter. This saves the wanted XML as a string without the declaration. Plain saveXML() without parameter would have saved the root node as a string including the declaration. Thus:

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

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

This also works of course, when you wish to return the root element:

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

ADDITION

I noticed that you wish to add something to the SOAP header instead of to the body.
This is a little tricky too but it can be achieved - I hope the below will fit your needs.

First, adding header details can only be done within the function script, and then the function will have to declare the server variable as global in order to refer to the globally (outside the function) declared one, as follows:

<?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();
?>

Note that it is required to first construct a SoapVar from the array; if you feed the array to the header directly you get ugly item/key and item/value nodes.

The above leads to the following return structure:

<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 に答える