快速启动

这一页提供了对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');
不想读RFC 3986?这里有一些关于base_uri是如何用另一个URI解决的快速例子。 . 。 。 。 。
base_uriURI结果
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
(可调用) 在网上传输HTTP请求的函数。该 函数是用一个Psr7\HttpMessage\RequestInterface和传输选项数组来调用的。 的传输选项,并且必须返回一个 GuzzleHttp\Promise\PromiseInterface,它是用一个 Psr7\Http\Message\ResponseInterface在成功时被满足。
...
(mixed) 所有传递给构造函数的其他选项将作为默认的 请求选项,用于客户端创建的每个请求。

发送请求

客户端上的魔法方法使得发送同步请求变得容易。

$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\StreamInterfacebody 请求选项。

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']
]);

POST/表单请求

除了使用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 接受一个数组的 关联数组,其中每个关联数组包含以下键。

  • name: (required, string) 与表单字段名的键映射。
  • 内容。(required, mixed) 提供一个字符串来发送文件的内容。 文件的内容,提供一个 fopen 资源以从一个 或提供一个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'
            ]
        ]
    ]
]);

Cookies

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来禁用重定向。
  • 传递一个包含'max'键的关联数组,以指定最大重定向数量。 重定向的数量,并可选择提供一个'strict'键值来指定 是否使用严格的RFC兼容的重定向(意味着重定向POST 与大多数浏览器所做的一样,即用POST请求重定向 用GET请求重定向POST请求)。
$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/BadResponseExceptionGuzzleHttpException/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_*处理程序在使用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
定义使用 "https "协议发送请求时要使用的代理。
NO_PROXY
定义了不应该使用代理的URL。参见proxy 的用法。

相关ini设置

Guzzle在配置客户端时可以利用PHP ini设置。

openssl.cafile
指定磁盘上PEM格式的CA文件的路径,以便在通过 "https "发送请求时使用。 请求时使用。参见。https://wiki.php.net/rfc/tls-peer-verification#phpini_defaults