PHP 網絡請求插件 Guzzle 入門(二)

PHP 網絡請求插件 Guzzle 入門(一)

 

Guzzle的使命就是模擬瀏覽器作爲客戶端請求獲得資源,所以Guzzle的功能主要就是請求數據和獲取數據。

Guzzle整個邏輯生命過程就是:建立Client客戶端實例------>填寫請求選項------->觸發需要的請求函數------->reponse(獲得返回值)。 (如果需要,可以加入異步、併發)。整個請求返回過程大致就是這樣。Guzzle裏還特意加入了中間件來處理我們特有的請求功能。如果需要可以在請求時轉向中間件。

下面我們用代碼瞭解一下Guzzle一般的工作工程。通過註冊樹的方式建立了一個類,封裝了Guzzle常見的Get、Post、異步與併發。

通過這個類的實現,我們基本可以清楚瞭解Guzzle的使用。當然更多的功能就是看我們怎樣去填充請求選項。請求選項可以參考Guzzle的中文文檔,根據不同需求來擴展此類。此類來源於noodles1994的博客文章與代碼:https://guzzle-cn.readthedocs.io/zh_CN/latest/index.html#。經過測試稍微修改了源代碼,noodles1994對返回值都做了json解析,但是我們做測試時不一定獲得的時json編碼。如果我們硬解析肯定會出錯。修改後以便測試使用與學習。還有一點就是在異常捕獲時,我故意在一處使用Throwable異常類,看看是否會捕獲到異常信息。

<?php
/*
 * @ProjectName: 開軟PHP實驗室
 * @company:河南省開軟網絡科技有限公司 
 * @Description: 
 * @Copyright:木蘭寬鬆許可證第1版(2019年8月5日中國有了自己的開源許可證,爲了支持與好玩咱也加上)
 * @Author: 古劍楠 
 * @Date: 2019-10-26 13:22:15 
 * @Last Modified by: 古劍楠
 * @Last Modified time: 2019-10-26 13:22:35
 */
namespace sdk;
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Promise;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;

//註冊樹模式  測試時一定要搭建好環境  見第一篇
class Guzzle
{
    //註冊樹容器
    private static $guzzle = [];

     /**
     * 釋放資源
     */
    public static function destoryAll()
    {
        //如果註冊樹容器爲空
        if( count(self::$guzzle) === 0 )
        {
            return TRUE;
        }

        //遍歷註冊樹銷燬
        foreach (self::$guzzle as $obj)
        {
            $obj = null;
        }
    }

    /**
     * 實例化guzzle(單例)
     * @param $base_uri
     * @return bool
     * */
    private static function init($base_uri)
    {
        if(!empty($base_uri))
        {
            if( !isset(self::$guzzle[$base_uri]) )
            {
                self::$guzzle[$base_uri] = new Client([
                    // 基URI
                    'base_uri' => $base_uri,
                    // 請求選項
                    'timeout'  => 10.0,
                ]);

                return True;
            }
            else
            {
                return True;
            }
        }
        else
        {
            return FALSE;
        }
    }

    /**
     * 獲取guzzle實例
     * @param $base_uri
     * @return bool|obj
     **/
    private static function getGuzzle($base_uri) 
    {
        if(Guzzle::init($base_uri) == FALSE)
        {
            return FALSE;
        }
        return self::$guzzle[$base_uri];
    }


    /**
     * get請求
     * @param string $base_uri   設置uri
     * @param string $api 請求api
     * @param array $headers 請求頭
     * @return mixed
     * @Throwable
     */
    public static function guzzleGet($base_uri, $api, $headers = []) 
    {
        $guzzleGetHandel = Guzzle::getGuzzle($base_uri);

        try
        {
            $data = [
                'headers' => $headers,
            ];
            $response = $guzzleGetHandel->get($api, $data);
            $responseCode = $response->getStatusCode();
            $responseBody = $response->getBody();
            $responseBody = $responseBody->getContents();

            //返回沒有處理的數據
            return $responseBody;
        }
        catch (RequestException $e)
        {
            echo $e->getMessage();
        }
    }


    /**
     * get請求(異步)
     * @param string $base_uri
     * @param string $api 請求api
     * @param array $headers 請求頭
     * @return mixed
     * @Throwable
     */
    public static function guzzleGetAsync($base_uri, $api, $headers = [])
    {
        
        $guzzleGetHandel = Guzzle::getGuzzle($base_uri);

        try
        {
            $data = [
                'headers' => $headers,
            ];
            $promises = [$guzzleGetHandel->getAsync($api, $data)];
            $response = Promise\unwrap($promises);

            //因爲用到了併發的功能。給$promises傳遞數組就是調用併發。爲了安全使用foreach便利一下。
            foreach ($response as $k => $v)
            {
                $responseBody =  $v->getBody()->getContents();   //獲取server端返回值
            }

            return $responseBody;
        }
        catch (Throwable $e)
        {
            echo "錯誤";
            echo $e->getMessage();
        }
    }


    /**
     * get請求(並行異步)
     * @param string $base_uri   設置uri
     * @param string $api 請求api
     * @param array $headers 請求頭
     * @return mixed
     * @throws \Exception
     */
    public static function guzzleGetAsyncParallel($base_uri, Array $api)
    {
        $guzzleGetHandel = Guzzle::getGuzzle($base_uri);
        try
        {
            $promises = [];
            $info = [];
            if(!empty($api))
            {
                foreach ($api as $value)
                {
                    array_push($promises, $guzzleGetHandel->getAsync($value));
                }
            }
            $response = Promise\unwrap($promises);   //客戶端發起請求並等待所有的請求結束再返回結果
            foreach ($response as $k => $v)
            {
                $responseBody[] =  $v->getBody()->getContents();   //獲取server端返回值
            }
            return $responseBody;
        }
        catch (RequestException $e)
        {
            throw new \Exception($e->getMessage());
        }
    }


    /**
     * post請求
     * @param string $base_uri   設置uri
     * @param string $api   請求api
     * @param array $post_data   請求數據
     * @param array $headers  請求頭
     * @param string $type   請求類型 json
     * @param string $cookie  請求cookies
     * @return mixed
     * @throws \Exception
     */
    public static function guzzlePost($base_uri, $api, $post_data = [], $headers = [], $type = 'json', $cookie = '') 
    {
        $guzzlePostHandle = Guzzle::getGuzzle($base_uri);
        try
        {
            if($type === 'json')
            {
                $data = [
                    'headers' => $headers,
                    'json' => $post_data,
                    'cookies' => $cookie,
                ];
            }
            else
            {
                $data = [
                    'headers' => $headers,
                    'body' => $post_data,
                    'cookies' => $cookie,
                ];
            }
            $response = $guzzlePostHandle->post($api, $data);
            $responseCode = $response->getStatusCode();
            $responseBody = $response->getBody()->getContents();
            return $responseBody;
        }
        catch (RequestException $e)
        {
            throw new \Exception($e->getMessage());
        }
    }


    /**    
     * post請求(異步)
     * @param string $base_uri   設置uri
     * @param string $api  請求api
     * @param array $post_data  請求數據
     * @param array $headers  請求頭
     * @param string $type  請求類型 json
     * @param string $cookie   請求cookies
     * @return array|mixed
     * @throws \Exception
     */
    public static function guzzlePostAsync($base_uri, $api, $post_data = [], $headers = [], $type = 'json', $cookie = '') 
    {
        $guzzlePostHandle = Guzzle::getGuzzle($base_uri);
        $responseBody = [];
        try
        {
            if($type === 'json')
            {
                $data = [
                    'headers' => $headers,
                    'json' => $post_data,
                    'cookies' => $cookie,
                ];
            }else{
                $data = [
                    'headers' => $headers,
                    'body' => $post_data,
                    'cookies' => $cookie,
                ];
            }
            $promises = [$guzzlePostHandle->postAsync($api, $data)];
            $response = Promise\unwrap($promises);
            foreach ($response as $k => $v)
            {
                $responseBody = $v->getBody()->getContents();   //獲取server端返回值  如果返回數據是json需要json解碼
            }
            return $responseBody;
        }
        catch (RequestException $e)
        {
            throw new \Exception($e->getMessage());
        }
    }

    。。。。。。。。。。。

}

-----------------------------------Guzzle的簡單使用完結---------------------------------------------------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章