GUZZLE7案例

版本说明

guzzle/guzzle 是 GuzzleHttp 第 3 版的一个较早的版本,它是在 GuzzleHttp 之前最受欢迎的版本之一,但它已经不再维护。
guzzlehttp/guzzle 是 GuzzleHttp 第 6 版的一个分支,它是目前推荐使用的 GuzzleHttp 版本。它也提供了更好的 PSR 支持和更好的异步请求处理方式

要求

  • PHP >= 7.2.5
  • 如果使用stream,必须开启allow_url_fopen
  • 如果使用curl,curl扩展版本必须>= 7.19.4

安装

composer require guzzlehttp/guzzle:^7.0

快速启动

require_once 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
    'base_uri' => 'http://httpbin.org',
    'timeout' => 2.0, //超时时间2秒
]);
// 发送请求 http://httpbin.org/test
$response = $client->request('GET', 'test');
// 发送请求 http://httpbin.org/root
$response = $client->request('GET', '/root');
//也可以这样发起请求
$response = $client->get('http://httpbin.org/get');
$response = $client->delete('http://httpbin.org/delete');
$response = $client->head('http://httpbin.org/get');
$response = $client->options('http://httpbin.org/get');
$response = $client->patch('http://httpbin.org/patch');
$response = $client->post('http://httpbin.org/post');
$response = $client->put('http://httpbin.org/put');
//可以先实例化Request,再发起请求
use GuzzleHttp\Psr7\Request;
$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);

发送异步请求

$promise = $client->getAsync('http://httpbin.org/get');
$promise = $client->deleteAsync('http://httpbin.org/delete');
$promise = $client->headAsync('http://httpbin.org/get');
$promise = $client->optionsAsync('http://httpbin.org/get');
$promise = $client->patchAsync('http://httpbin.org/patch');
$promise = $client->postAsync('http://httpbin.org/post');
$promise = $client->putAsync('http://httpbin.org/put');
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
)->wait();

并发发送请求

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client(['base_uri' => 'http://httpbin.org/']);
// 不阻塞发起每个请求
$promises = [
    'image' => $client->getAsync('/image'),
    'png'   => $client->getAsync('/image/png'),
    'jpeg'  => $client->getAsync('/image/jpeg'),
    'webp'  => $client->getAsync('/image/webp')
];
//等待全部请求返回,如果其中一个请求失败会抛出异常
$responses = Promise\Utils::unwrap($promises);
//等待全部请求返回,允许某些请求失败
$responses = Promise\Utils::settle($promises)->wait();

使用Response

$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK
//header是否存在Content-Length
if ($response->hasHeader('Content-Length')) {
    echo "It exists";
}

//获取Content-Length的值
echo $response->getHeader('Content-Length')[0];
//全部header
foreach ($response->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

//getBody返回的是实现了StreamInterface接口的流对象
$body = $response->getBody();
//StreamInterface实现了__toString()方法,可以直接输出
echo $body;
//显示转换成字符串
$stringBody = (string) $body;
//当作流一样使用,使用read方法读取
$tenBytes = $body->read(10);
//读取剩余内容
$remainingBytes = $body->getContents();

query参数的几种写法

//1
$response = $client->request('GET', 'http://httpbin.org?foo=bar');
//2 会自动使用http_build_query 
$client->request('GET', 'http://httpbin.org', [
    'query' => ['foo' => 'bar']
]);
//3
$client->request('GET', 'http://httpbin.org', ['query' => 'foo=bar']);

上传数据

//$body是字符串数据
$r = $client->request('POST', 'http://httpbin.org/post', [
    'body' => 'raw data'
]);

// $body是文件句柄
$body = Psr7\Utils::tryFopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

// body是PSR-7 stream流.
$body = Psr7\Utils::streamFor('hello!');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

表单上传

// application/x-www-form-urlencoded
$response = $client->request('POST', 'http://httpbin.org/post', [
    'form_params' => [
        'field_name' => 'abc',
        'other_field' => '123',
        'nested_field' => [
            'nested' => 'hello'
        ]
    ]
]);

//multipart/form-data
use GuzzleHttp\Psr7;

$response = $client->request('POST', 'http://httpbin.org/post', [
    'multipart' => [
        [
            'name'     => 'field_name',//表单name
            'contents' => 'abc'//表单值
        ],
        [
            'name'     => 'file_name',//文件名
            'contents' => Psr7\Utils::tryFopen('/path/to/file', 'r')//文件句柄
        ],
        [
            'name'     => 'other_file',//没太看懂,前面两种够用了
            'contents' => 'hello',
            'filename' => 'filename.txt',
            'headers'  => [
                'X-Foo' => 'this is an extra header to include'
            ]
        ]
    ]
]);

Cookies

//组装cookie
$jar = \GuzzleHttp\Cookie\CookieJar::fromArray(
    [
        'some_cookie' => 'foo',
        'other_cookie' => 'barbaz1234'
    ],
    'example.org' //域名
);

//带cookies发起请求
$jar = new \GuzzleHttp\Cookie\CookieJar;
$r = $client->request('GET', 'http://httpbin.org/cookies', [
    'cookies' => $jar
]);

//client共享cookie
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'http://httpbin.org/cookies');

异常树

. \RuntimeException
└── TransferException (implements GuzzleException)
    ├── ConnectException (implements NetworkExceptionInterface) //网络错误
    └── RequestException
        ├── BadResponseException
        │   ├── ServerException //500错误
        │   └── ClientException //400错误
        └── TooManyRedirectsException //太多重定向

常用的请求

//BASIC 授权
$client->request('GET', '/get', ['auth' => ['username', 'password']]);

//DIGEST授权
$client->request('GET', '/get', [
    'auth' => ['username', 'password', 'digest']
]);

//连接超时时间,0为无限期
$client->request('GET', '/delay/5', ['connect_timeout' => 3.14]);

//设置header
// Set various headers on a request
$client->request('GET', '/get', [
    'headers' => [
        'User-Agent' => 'testing/1.0',
        'Accept'     => 'application/json',
        'X-Foo'      => ['Bar', 'Baz']
    ]
]);

//请求超时
$client->request('GET', '/delay/5', ['timeout' => 3.14]);

总结

再见自己写的curl函数,拥抱guzzlehttp,还支持异步请求,推荐指数:五老星

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容