PHPはwsdlを処理します

高洛峰
高洛峰オリジナル
2016-10-20 14:18:581658ブラウズ

0x00 はじめに

私は最近インターフェイスを書いています。これまで、インターフェイスのデータ送信は json または xml 形式を使用して送信または取得されていました。しかし今回、サードパーティと共同でデバッグする際に、彼らは wsdl 形式を提供してくれました。すぐに SB に変更されました...

テスト コードを Google で検索すると、テストはサードパーティのインターフェイスを呼び出してステータス 200 を返します。このまま何も起こらなければ終わるだろうと思っていたのですが、近づいてみると、インターフェースをいくら呼び出しても正しいデータが返ってこないことが分かりました。その後、ログを確認したところ、渡されたパラメータをまったく受け取っていないことがわかり、問題を解決するまで、午後から夕方まで混乱していました。なかなか興味深い内容だったので、まずは書いてみました。

0x01 wsdl とは何ですか? 誰かの話によると、Web サーバーの定義を記述するために使用される XML 形式のドキュメント、つまり Web サーバーのメソッドとパラメーターの記述です。

参照: http://baike.baidu.com/link?url=R7x3FdekxbndR4SlzQLZE_2m1ebpt_SWt9IMjoHSErvLlbZ3-hwhR3ERrinXS1xZaDvkYFpxWnUchrk34_WkZq

http://api.test.cn/xwebservice をリクエストする場合「wsdl」、このように終わるのはいつですか? wsdl の URL を設定すると、一連の XML 構造化データが提供されます。

そうです、ただのしこりです…

PHPはwsdlを処理します次に、それをどう理解するか、それに書かれている方法が鍵で、それ以外は無駄です。

0x02 説明ドキュメントの理解

この XML ドキュメントを最初に見たとき、私は混乱しましたが、PHP 拡張機能を使用した後、より明確になりました。

<?php
$client = new SoapClient(&#39;http://api.test.cn/xwebservices/testServer?wsdl&#39;);

print "\n提供的方法\n";
print_r($client->__getFunctions());
print "相关的数据结构\n";
print_r($client->__getTypes());
print "\n\n";

PHPはwsdlを処理しますここではSOAP拡張機能を使用します。この拡張機能は、最終的には、パラメータの送信を実現するためにも使用されます。

上の図からわかるように、このインターフェイスには次の 3 つのメソッドが用意されています。

xxxxUserInfo

xxxxResumeNum

download**

関連するデータ構造は、メソッド内のパラメータ名とパラメータ タイプを参照します。たとえば、xxxxUserInfo メソッドには 3 つの文字列型パラメータが必要です。それぞれ in0、in1、in2 に対応します。

注意

ここでのパラメーター キーは in0 である必要があります。これは、配列を必要としない任意のパラメーター名であり、ユーザー定義か、双方が合意したものです。インターフェイス メソッドの作成を開始したとき、err_msg (エラー情報を示す)、err_code (エラー コーディングを示す)、および date (送信される最終データ) など、インターフェイス コピーに指定されているパラメーターの説明に基づいて送信を実行しました。次に、それを順序付き配列に変更し、対応するパラメータを 1 つずつ入力します。このとき、キーは 0 ~ 2 です。しかし、試してみてもやはりうまくいきませんでした。最後に、試してみようという気持ちで、キー名として int0 を、値として対応する err_msg の内容を使用してみました。 OK~、完璧な解決策です。

コード:

<?php

/**
 * @author 0x584A
 * 获取WSDL接口数据
 */
class getwsdlTest extends PHPUnit_Framework_TestCase
{
    public $apiurl = &#39;http://api.test.cn/xwebservices/testServer?wsdl&#39;;
    private static $soapClientHandler;
    private $infoArr = [
        &#39;err_msg&#39; => &#39;false&#39;,
        &#39;err_code&#39; => &#39;0&#39;,
        &#39;date&#39; => &#39;此处是要传输的数据&#39;
    ];

    public function setUp()
    {
        $client = new SoapClient(&#39;http://api.test.cn/xwebservices/testServer?wsdl&#39;);
        print "提供的方法\n";
        print_r($client->__getFunctions());
        print "相关的数据结构\n";
        print_r($client->__getTypes());
        print "\n\n";
    }

    /**
     * xxxxUserInfo方法
     */
    public function testxxxxUserInfoData()
    {
        try {
            $ApiInfo = $this->infoArr;

            //set request param
            $parameter = array(
                &#39;in0&#39; => $ApiInfo[&#39;err_msg&#39;],
                &#39;in1&#39; => $ApiInfo[&#39;err_code&#39;],
                &#39;in2&#39; => $ApiInfo[&#39;date&#39;]
            );

            $result = $this->getSoapClientHandler()->synchUserInfo($parameter);

            //调用结果返回异常
            if (!$result instanceof stdClass) {
                throw new Exception("调用synchUserInfo结果出现异常:" . json_encode($result));
            }

            //调用接口状态码,输出对应错误详情
            if ($result->out == &#39;01&#39;) {
                throw new Exception("调用synchUserInfo=>error:" . $result->out . ",msg:接口数据异常");
            }

            $xml_parser = xml_parser_create();
            if (!xml_parse($xml_parser, $result->out, true)) {
                xml_parser_free($xml_parser);
                throw new Exception("调用synchUserInfo返回的不是一个xml结构体");
            }
            xml_parser_free($xml_parser);
            //XXE
            libxml_disable_entity_loader(true);
            $xml = simplexml_load_string($result->out, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA);
            // 输出参数
            var_dump($xml->data);
            echo " 成功".PHP_EOL;
        } catch (SoapFault $soapFault) {
            throw new Exception($soapFault->getMessage() . $this->getSoapClientHandler()->__getLastResponse());
        }
    }

    /**
     * @description getSoapClientHandler
     */
    public function getSoapClientHandler()
    {
        if (!self::$soapClientHandler) {
            self::$soapClientHandler = new SoapClient($this->getSynchApi());
        }
        return self::$soapClientHandler;
    }

    /**
     * @description getSynchApi
     */
    public function getSynchApi()
    {
        return $this->apiurl;
    }

}
?>

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。