这一页提供了对Guzzle的快速介绍和介绍性的例子。 如果你还没有安装Guzzle,请到安装 页面。
你可以使用一个GuzzleHttpClientInterface
对象来发送请求。
use GuzzleHttp\Client;
$client = new Client([
// Base URI is used with relative requests
'base_uri' => 'http://httpbin.org',
// You can set any number of default request options.
'timeout' => 2.0,
]);
客户端在Guzzle中是不可改变的,这意味着你不能在客户端创建后改变它所使用的默认值。
客户端构造函数接受一个选项的关联数组。
base_uri
(string|UriInterface) 客户端的基本URI,被合并到相对的 URIs。可以是一个字符串或UriInterface的实例。当一个相对URI 的时候,客户端将使用UriInterface中描述的规则将基本URI和 中所描述的规则,将基础URI和相对URI结合起来。 RFC 3986, section 5.2.
//创建一个有基本URI的客户端
$client = new GuzzleHttp/Client(['base_uri' => 'https://foo.com/api/']);
// 发送一个请求到 https://foo.com/api/test
$response = $client->request('GET', 'test');
// 发送一个请求到 https://foo.com/root
$response = $client->request('GET', '/root');
base_uri
是如何用另一个URI解决的快速例子。
.
。
。
。
。
base_uri | URI | 结果 |
---|---|---|
http://foo.com |
/bar |
http://foo.com/bar |
http://foo.com/foo |
/bar |
http://foo.com/bar |
http://foo.com/foo |
bar |
http://foo.com/bar |
http://foo.com/foo/ |
bar |
http://foo.com/foo/bar |
http://foo.com |
http://baz.com |
http://baz.com |
http://foo.com/?bar |
bar |
http://foo.com/bar |
handler
Psr7\HttpMessage\RequestInterface
和传输选项数组来调用的。
的传输选项,并且必须返回一个
GuzzleHttp\Promise\PromiseInterface
,它是用一个
Psr7\Http\Message\ResponseInterface
在成功时被满足。...
客户端上的魔法方法使得发送同步请求变得容易。
$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');
你可以创建一个请求,然后在你准备好的时候和客户端一起发送请求。
use GuzzleHttp\Psr7\Request;
$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);
客户端对象在如何传输请求方面提供了大量的灵活性 包括默认的请求选项,默认的处理程序栈中间件 和一个基本URI,允许你用相对的URI发送请求。 与相对URI。
你可以在文档的处理程序和中间件页中找到更多关于客户端中间件的信息。
你可以使用客户端提供的神奇方法发送异步请求。
$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');
你也可以使用客户端的sendAsync()和requireAsync()方法。
use GuzzleHttp\Psr7\Request;
// Create a PSR-7 request object to send
$headers = ['X-Foo' => 'Bar'];
$body = 'Hello!';
$request = new Request('HEAD', 'http://httpbin.org/head', $headers, $body);
$promise = $client->sendAsync($request);
// Or, if you don't need to pass in a request instance:
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
由这些方法返回的承诺实现了
Promises/A+ spec,由
Guzzle promises库。这意味着
你可以从承诺中链出then()
调用。这些然后的调用是
要么以一个成功的Psr\HttpMessage\ResponseInterface
完成,要么
拒绝一个异常。
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();
}
);
你可以使用承诺和异步请求并发地发送多个请求。
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client(['base_uri' => 'http://httpbin.org/']);
// Initiate each request but do not block
$promises = [
'image' => $client->getAsync('/image'),
'png' => $client->getAsync('/image/png'),
'jpeg' => $client->getAsync('/image/jpeg'),
'webp' => $client->getAsync('/image/webp')
];
// Wait for the requests to complete; throws a ConnectException
// if any of the requests fail
$responses = Promise\Utils::unwrap($promises);
// You can access each response using the key of the promise
echo $responses['image']->getHeader('Content-Length')[0];
echo $responses['png']->getHeader('Content-Length')[0];
// Wait for the requests to complete, even if some of them fail
$responses = Promise\Utils::settle($promises)->wait();
// Values returned above are wrapped in an array with 2 keys: "state" (either fulfilled or rejected) and "value" (contains the response)
echo $responses['image']['state']; // returns "fulfilled"
echo $responses['image']['value']->getHeader('Content-Length')[0];
echo $responses['png']['value']->getHeader('Content-Length')[0];
当你有不确定的请求量时,你可以使用GuzzleHttp/Pool
对象。
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
$client = new Client();
$requests = function ($total) {
$uri = 'http://127.0.0.1:8126/guzzle-server/perf';
for ($i = 0; $i < $total; $i++) {
yield new Request('GET', $uri);
}
};
$pool = new Pool($client, $requests(100), [
'concurrency' => 5,
'fulfilled' => function (Response $response, $index) {
// this is delivered each successful response
},
'rejected' => function (RequestException $reason, $index) {
// this is delivered each failed request
},
]);
// Initiate the transfers and create a promise
$promise = $pool->promise();
// Force the pool of requests to complete.
$promise->wait();
或者使用一个闭包,一旦池子调用闭包就会返回一个承诺。
$client = new Client();
$requests = function ($total) use ($client) {
$uri = 'http://127.0.0.1:8126/guzzle-server/perf';
for ($i = 0; $i < $total; $i++) {
yield function() use ($client, $uri) {
return $client->getAsync($uri);
};
}
};
$pool = new Pool($client, $requests(100));
在前面的例子中,我们检索了一个$response
变量,或者我们被
从一个承诺中得到一个响应。响应对象实现了一个PSR-7
响应,Psr\Http\Message\ResponseInterface
,并包含很多
有用的信息。
你可以得到响应的状态代码和原因短语。
$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK
你可以从响应中检索头信息。
// Check if a header exists.
if ($response->hasHeader('Content-Length')) {
echo "It exists";
}
// Get a header from the response.
echo $response->getHeader('Content-Length')[0];
// Get all of the response headers.
foreach ($response->getHeaders() as $name => $values) {
echo $name . ': ' . implode(', ', $values) . "\r\n";
}
响应的主体可以使用getBody
方法进行检索。响应体可以作为一个字符串使用,也可以转换为一个字符串,或者作为一个类似流的对象使用。
$body = $response->getBody();
// Implicitly cast the body to a string and echo it
echo $body;
// Explicitly cast the body to a string
$stringBody = (string) $body;
// Read 10 bytes from the body
$tenBytes = $body->read(10);
// Read the remaining contents of the body as a string
$remainingBytes = $body->getContents();
你可以通过几种方式在请求中提供查询字符串参数。
你可以在请求的URI中设置查询字符串参数。
$response = $client->request('GET', 'http://httpbin.org?foo=bar');
你可以使用query
请求选项指定查询字符串参数作为一个数组。
$client->request('GET', 'http://httpbin.org', [
'query' => ['foo' => 'bar']
]);
以数组形式提供选项将使用PHP的http_build_query
函数来格式化查询字符串。
最后,你可以提供query
请求选项作为一个字符串。
$client->request('GET', 'http://httpbin.org', ['query' => 'foo=bar']);
Guzzle提供了几种上传数据的方法。
你可以通过传递一个字符串来发送包含数据流的请求。
资源返回fopen
,或者一个
Psr\Http\Message\StreamInterface
到body
请求选项。
use GuzzleHttp\Psr7;
// Provide the body as a string.
$r = $client->request('POST', 'http://httpbin.org/post', [
'body' => 'raw data'
]);
// Provide an fopen resource.
$body = Psr7\Utils::tryFopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
// Use the Utils::streamFor method to create a PSR-7 stream.
$body = Psr7\Utils::streamFor('hello!');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
上传JSON数据并设置适当的头的简单方法是使用json
请求选项。
$r = $client->request('PUT', 'http://httpbin.org/put', [
'json' => ['foo' => 'bar']
]);
除了使用body
请求选项来指定请求的原始数据外,Guzzle还提供了关于发送POST数据的有用的抽象概念。
发送application/x-www-form-urlencoded
POST请求需要你在form_params
请求选项中指定POST域作为一个数组。
$response = $client->request('POST', 'http://httpbin.org/post', [
'form_params' => [
'field_name' => 'abc',
'other_field' => '123',
'nested_field' => [
'nested' => 'hello'
]
]
]);
你可以将文件和表单一起发送(multipart/form-data
POST请求)。
使用 multipart
请求选项。multipart
接受一个数组的
关联数组,其中每个关联数组包含以下键。
Psr\HttpMessageStreamInterface
以从PSR-7流中传输内容。
内容来自PSR-7流。use GuzzleHttp\Psr7;
$response = $client->request('POST', 'http://httpbin.org/post', [
'multipart' => [
[
'name' => 'field_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'
]
]
]
]);
Guzzle可以为你维护一个cookie会话,如果使用的是
cookies
请求选项。当发送请求时,cookies
选项
必须被设置为GuzzleHttp/CookieCookieJarInterface
的一个实例。
// Use a specific cookie jar
$jar = new \GuzzleHttp\Cookie\CookieJar;
$r = $client->request('GET', 'http://httpbin.org/cookies', [
'cookies' => $jar
]);
如果你想为所有的请求使用一个共享的cookie罐,你可以在客户端构造函数中把cookie
设置为true。
// Use a shared client cookie jar
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'http://httpbin.org/cookies');
对于GuzzleHttp\CookieCookieJarInterface
存在不同的实现。
GuzzleHttp\Cookie\CookieJar
类将cookie存储为一个数组。GuzzleHttp\Cookie/FileCookieJar
类使用JSON格式的文件持久化非会话cookies。
使用一个JSON格式的文件。GuzzleHttp\Cookie/SessionCookieJar
类将cookie持久化在
客户端会话中。你可以用命名的构造函数fromArray(array $cookies, $domain)
手动设置cookies到一个cookie罐。
$jar = \GuzzleHttp\Cookie\CookieJar::fromArray(
[
'some_cookie' => 'foo',
'other_cookie' => 'barbaz1234'
],
'example.org'
);
你可以用getCookieByName($name)
方法获得一个cookie的名称,该方法返回一个GuzzleHttp\Cookie/SetCookie
实例。
$cookie = $jar->getCookieByName('some_cookie');
$cookie->getValue(); // 'foo'
$cookie->getDomain(); // 'example.org'
$cookie->getExpires(); // expiration date as a Unix timestamp
由于有了toArray()方法,这些cookie也可以被取到一个数组中。
GuzzleHttp\Cookie/CookieJarInterface
接口扩展了
Traversable
所以它可以在一个foreach循环中被迭代。
Guzzle会自动跟随重定向,除非你告诉它不要这样做。你可以使用allow_redirects
请求选项自定义重定向行为。
true
以启用正常重定向,最大数量为5次。
重定向。这是默认设置。false
来禁用重定向。$response = $client->request('GET', 'http://github.com');
echo $response->getStatusCode();
// 200
下面的例子显示,可以禁用重定向。
$response = $client->request('GET', 'http://github.com', [
'allow_redirects' => false
]);
echo $response->getStatusCode();
// 301
树状视图
下面的树状视图描述了Guzzle异常是如何相互依赖的。
. \RuntimeException
└── TransferException (implements GuzzleException)
├── ConnectException (implements NetworkExceptionInterface)
└── RequestException
├── BadResponseException
│ ├── ServerException
│ └── ClientException
└── TooManyRedirectsException
Guzzle对传输过程中发生的错误会抛出异常。
一个GuzzleHttpException\ConnectException
异常会在网络错误时被抛出。
异常。这个异常延伸自
GuzzleHttpException/TransferException
。
如果GuzzleHttpException\ClientException
被抛出,用于处理400
级的错误,如果http_errors
请求选项被设置为 "true"。这个
异常是从GuzzleHttp/Exception/BadResponseException
和
GuzzleHttpException/BadResponseException
扩展自
GuzzleHttpException\RequestException
。
使用GuzzleHttp\Psr7。
使用GuzzleHttp\Exception\ClientException。
try {
$client->request('GET', 'https://github.com/_abc_123_404');
} catch (ClientException $e) {
echo Psr7\Message::toString($e->getRequest())。
echo Psr7\Message::toString($e->getResponse())。
}
一个GuzzleHttpException\ServerException
会被抛出,用于处理500级别的
如果http_errors
请求选项被设置为 "true",就会抛出一个500级别的错误。这个
异常是从GuzzleHttp/Exception/BadResponseException
延伸出来的。
一个GuzzleHttpException\TooManyRedirectsException
被抛出,当太多的重定向被跟踪时。
抛出,因为有太多的重定向。这个异常是从GuzzleHttp/Exception/RequestException
延伸出来的。
上述所有的异常都是从GuzzleHttpException\TransferException
延伸而来的。
Guzzle暴露了一些环境变量,可以用来定制库的行为。
GUZZLE_CURL_SELECT_TIMEOUT
curl_multi_select()选择curl处理时的持续时间(秒)。
使用curl_multi_select()
对curl句柄进行选择时使用的时间(秒)。有些系统
有些系统对PHP的curl_multi_select()
的实现有问题,在这种情况下
调用这个函数的结果总是要等待最大的超时时间
超时。
HTTP_PROXY
定义了使用 "http "协议发送请求时要使用的代理
。注意:由于HTTP_PROXY变量在某些(CGI)环境下可能包含任意的用户输入,该变量只在CLI SAPI上使用。参见https://httpoxy.org以了解更多信息。
HTTPS_PROXY
NO_PROXY
Guzzle在配置客户端时可以利用PHP ini设置。
openssl.cafile