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的简单使用完结---------------------------------------------------------

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