php處理wsdl

0x00 前言

近期一直在寫接口,在此以前接口數據傳輸都是使用json或者xml格式進行傳輸或獲取的。但此次和第三方聯調時,他們給予的是wsdl格式。瞬間秒變SB...php

google到測試用code,測試調用第三方接口返回狀態200。覺得沒啥事了能夠就此結束了,跟近後才發現,無論怎麼調用他們接口就是沒有正確的數據回顯。隨後他們那邊查看log後發現,壓根傳過去的參數他們沒有接收到,懵逼了一下午到晚上才解決了這個問題。以爲挺有意思的,因此記下來先。web

0x01 wsdl是什麼

綜合某度上所說,它就是一個xml格式的文檔,用於描述Web Server的定義,也就是說是一個Web Server方法及參數說明。json

詳見:http://baike.baidu.com/link?url=R7x3FdekxbndR4SlzQLZE_2m1ebpt_SWt9IMjoHSErvLlbZ3-hwhR3ERrinXS1xZaDvkYFpxWnUchrk34_WkZqapi

當咱們請求http://api.test.cn/xwebservices/testServer?wsdl',相似這種結尾是?wsdl的URL時,會一坨xml結構的數據給你。數組

沒錯,就是一坨...數據結構

圖片描述

接下來,怎麼看懂它和它所說的方法纔是關鍵,其它都是白搭。測試

0x02 理解描述文檔

剛開始看這個xml文檔時是比較懵逼的,但用PHP的擴展處理下就明顯不少了。this

<?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服務擴展,最終咱們也是經過它來實現參數傳輸。google

在上面的圖片中能夠理解出,這個接口提供了三個方法,分別是:編碼

  • xxxxUserInfo

  • xxxxResumeNum

  • download**

相關的數據機構則是指方法中參數名稱,及參數類型。好比xxxxUserInfo方法,須要三個string類型的參數。分別對應in0in1in2

此處的傳參數key必然是in0,也就是一個無需數組,用戶自定義或雙方約定好的任意參數名稱。在開始寫接口方法的時候,我是根據接口文案中給予的參數說明如:err_msg(表示錯誤信息)err_code(表示錯誤編碼)date(傳輸的最終數據)進行傳輸的。後改成有序數組,挨個填入對應參數,此時key就是的02。可試過以後仍是沒什麼卵用,最終包着試一試的心態,嘗試一下將int0做爲鍵名,對應的err_msg內容做爲值。ok~,完美解決。

Code:

<?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;
    }

}
?>
相關文章
相關標籤/搜索