0x00 はじめに
最近インターフェイスを書いているのですが、以前はインターフェイスのデータ送信はjson形式やxml形式で送信または取得していました。しかし今回、サードパーティと共同でデバッグする際に、彼らは wsdl 形式を提供してくれました。瞬時に SB に変わります...
テスト コードを Google で検索すると、テストはサードパーティのインターフェイスを呼び出してステータス 200 を返します。このまま何も起こらなければ終わるだろうと思っていたのですが、近づいてみると、インターフェースをいくら呼び出しても正しいデータが返ってこないことが分かりました。その後、ログを確認したところ、渡されたパラメータをまったく受け取っていないことが分かり、午後から夕方まで混乱して問題が解決されました。なかなか興味深い内容だったので、まずは書いてみました。
0x01 wsdl
とは何か これまでの説明に基づいて、Web サーバーの定義を記述するために使用される XML 形式のドキュメントです。つまり、Web サーバーのメソッドとパラメーターの説明です。
参照: https://www.php.cn/faq/437443.html
リクエストする場合 http://api.test.cn/xwebservices / testServer?wsdl' は、?wsdl で終わるこの URL と同様に、一連の XML 構造化データが提供されます。
はい、ただの塊です...
次はそれをどう理解するか、その方法が鍵です、それ以外はすべて無駄だ。
0x02 説明ドキュメントの理解
この XML ドキュメントを最初に見たときは非常に混乱しましたが、PHP 拡張機能を使用すると、より明確になりました。
<?php $client = new SoapClient('http://api.test.cn/xwebservices/testServer?wsdl'); print "\n提供的方法\n"; print_r($client->__getFunctions()); print "相关的数据结构\n"; print_r($client->__getTypes()); print "\n\n";
ここでは SOAP 拡張機能を使用します。この拡張機能は、公式 PHP コピーで提供されている操作処理 WebServer サービス拡張機能です。最終的には、パラメーターの実現にも使用します。伝染 ; 感染。
上の図からわかるように、このインターフェイスには次の 3 つのメソッドが用意されています。
##関連するデータ構造は、メソッド内のパラメーター名とパラメーターのタイプを指します。たとえば、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 = 'http://api.test.cn/xwebservices/testServer?wsdl'; private static $soapClientHandler; private $infoArr = [ 'err_msg' => 'false', 'err_code' => '0', 'date' => '此处是要传输的数据' ]; public function setUp() { $client = new SoapClient('http://api.test.cn/xwebservices/testServer?wsdl'); 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( 'in0' => $ApiInfo['err_msg'], 'in1' => $ApiInfo['err_code'], 'in2' => $ApiInfo['date'] ); $result = $this->getSoapClientHandler()->synchUserInfo($parameter); //调用结果返回异常 if (!$result instanceof stdClass) { throw new Exception("调用synchUserInfo结果出现异常:" . json_encode($result)); } //调用接口状态码,输出对应错误详情 if ($result->out == '01') { 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, 'SimpleXMLElement', 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; } } ?>プロモーション:「
PHP チュートリアル
」以上がPHPはwsdlをどのように処理しますかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。