php 请求库 guzzle 的使用
<p>Guzzle是一个PHP的HTTP客户端,用来轻而易举地发送请求,并集成到我们的WEB服务上。</p><ul>
<li>接口简单:构建查询语句、POST请求、分流上传下载大文件、使用HTTP cookies、上传JSON数据等等。</li>
<li>发送同步或异步的请求均使用相同的接口。</li>
<li>使用PSR-7接口来请求、响应、分流,允许你使用其他兼容的PSR-7类库与Guzzle共同开发。</li>
<li>抽象了底层的HTTP传输,允许你改变环境以及其他的代码,如:对cURL与PHP的流或socket并非重度依赖,非阻塞事件循环。</li>
<li>中间件系统允许你创建构成客户端行为</li>
</ul>
<p>官方文档:https://guzzle-cn.readthedocs.io/zh_CN/latest/</p>
<p>github:https://github.com/guzzle/guzzle</p>
<h2 id="环境要求">环境要求</h2>
<ol>
<li>PHP 5.5.0</li>
<li>使用PHP的流, <code>allow_url_fopen</code> 必须在php.ini中启用。</li>
<li>要使用cURL,你必须已经有版本cURL >= 7.19.4,并且编译了OpenSSL 与 zlib。</li>
</ol>
<p>如果没有安装cURL,Guzzle处理HTTP请求的时候不再使用cURL,而是使用PHP流处理,或者你也可以提供自己的发送HTTP请求的处理方式。</p>
<h2 id="安装">安装</h2>
<pre><code>composer require guzzlehttp/guzzle:~6.0
</code></pre>
<p>该页面提供了Guzzle的快速入门以及列子,如果你还没有安装Guzzle请前往 安装 页面。</p>
<h2 id="发送请求">发送请求</h2>
<p>你可以使用Guzzle的 <code>GuzzleHttp\ClientInterface</code> 对象来发送请求。</p>
<h3 id="创建客户端">创建客户端</h3>
<pre><code>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,
]);
</code></pre>
<p>Client对象可以接收一个包含参数的数组:</p>
<ul>
<li>
<p><code>base_uri</code></p>
<p>(string|UriInterface) 基URI用来合并到相关URI,可以是一个字符串或者UriInterface的实例,当提供了相关uri,将合并到基URI,遵循的规则请参考 RFC 3986, section 2 章节。</p>
<pre><code>// Create a client with a base URI
$client = new GuzzleHttp\Client(['base_uri' => 'https://foo.com/api/']);
// Send a request to https://foo.com/api/test
$response = $client->request('GET', 'test');
// Send a request to https://foo.com/root
$response = $client->request('GET', '/root');
</code></pre>
<p>不想阅读RFC 3986?这里有一些关于 <code>base_uri</code> 与其他URI处理器的快速例子:</p>
<pre><code>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
</code></pre>
</li>
<li>
<p><code>handler</code></p>
<p>传输HTTP请求的(回调)函数。 该函数被调用的时候包含 <code>Psr7\Http\Message\RequestInterface</code> 以及参数数组,必须返回 <code>GuzzleHttp\Promise\PromiseInterface</code> ,成功时满足 <code>Psr7\Http\Message\ResponseInterface</code> 。 <code>handler</code> 是一个构造方法,不能在请求参数里被重写。</p>
</li>
<li>
<p><code>...</code></p>
<p>(混合) 构造方法中传入的其他所有参数用来当作每次请求的默认参数。</p>
</li>
</ul>
<h3 id="发送请求-1">发送请求</h3>
<p>Client对象的方法可以很容易的发送请求:</p>
<pre><code>$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');
</code></pre>
<p>你可以创建一个请求,一切就绪后将请求传送给client:</p>
<pre><code>use GuzzleHttp\Psr7\Request;
$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);
</code></pre>
<p>Client对象为传输请求提供了非常灵活的处理器方式,包括请求参数、每次请求使用的中间件以及传送多个相关请求的基URI。</p>
<p>你可以在 <em>Handlers and Middleware</em> 页面找到更多关于中间件的内容。</p>
<h3 id="异步请求">异步请求</h3>
<p>你可以使用Client提供的方法来创建异步请求:</p>
<pre><code>$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');
</code></pre>
<p>你也可以使用Client的 sendAsync() and requestAsync() 方法:</p>
<pre><code>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);
// Or, if you don't need to pass in a request instance:
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
</code></pre>
<p>这些方法返回了Promise对象,该对象实现了由 Guzzle promises library 提供的 Promises/A+ spec ,这意味着你可以使用 <code>then()</code> 来调用返回值,成功使用 <code>Psr\Http\Message\ResponseInterface</code> 处理器,否则抛出一个异常。</p>
<pre><code>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();
}
);
</code></pre>
<h3 id="并发请求">并发请求</h3>
<p>你可以使用Promise和异步请求来同时发送多个请求:</p>
<pre><code>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 on all of the requests to complete.
$results = Promise\unwrap($promises);
// You can access each result using the key provided to the unwrap
// function.
echo $results['image']->getHeader('Content-Length');
echo $results['png']->getHeader('Content-Length');
</code></pre>
<p>当你想发送不确定数量的请求时,可以使用 <code>GuzzleHttp\Pool</code> 对象:</p>
<pre><code>use GuzzleHttp\Pool;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
$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, $index) {
// this is delivered each successful response
},
'rejected' => function ($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();
</code></pre>
<h2 id="使用响应">使用响应</h2>
<p>前面的例子里,我们取到了 <code>$response</code> 变量,或者从Promise得到了响应,Response对象实现了一个PSR-7接口 <code>Psr\Http\Message\ResponseInterface</code> , 包含了很多有用的信息。</p>
<p>你可以获取这个响应的状态码和和原因短语(reason phrase):</p>
<pre><code>$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK
</code></pre>
<p>你可以从响应获取头信息(header):</p>
<pre><code>// Check if a header exists.
if ($response->hasHeader('Content-Length')) {
echo "It exists";
}
// Get a header from the response.
echo $response->getHeader('Content-Length');
// Get all of the response headers.
foreach ($response->getHeaders() as $name => $values) {
echo $name . ': ' . implode(', ', $values) . "\r\n";
}
</code></pre>
<p>使用 <code>getBody</code> 方法可以获取响应的主体部分(body),主体可以当成一个字符串或流对象使用</p>
<pre><code>$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();
</code></pre>
<h2 id="查询字符串参数">查询字符串参数</h2>
<p>你可以有多种方式来提供请求的查询字符串 你可以在请求的URI中设置查询字符串:</p>
<pre><code>$response = $client->request('GET', 'http://httpbin.org?foo=bar');
</code></pre>
<p>你可以使用 <code>query</code> 请求参数来声明查询字符串参数:</p>
<pre><code>$client->request('GET', 'http://httpbin.org', [
'query' => ['foo' => 'bar']
]);
</code></pre>
<p>提供的数组参数将会使用PHP的 <code>http_build_query</code> :</p>
<p>最后,你可以提供一个字符串作为 <code>query</code> 请求参数:</p>
<pre><code>$client->request('GET', 'http://httpbin.org', ['query' => 'foo=bar']);
</code></pre>
<h2 id="上传数据">上传数据</h2>
<p>Guzzle为上传数据提供了一些方法。 你可以发送一个包含数据流的请求,将 <code>body</code> 请求参数设置成一个字符串、 <code>fopen</code> 返回的资源、或者一个 <code>Psr\Http\Message\StreamInterface</code> 的实例。</p>
<pre><code>// Provide the body as a string.
$r = $client->request('POST', 'http://httpbin.org/post', [
'body' => 'raw data'
]);
// Provide an fopen resource.
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
// Use the stream_for() function to create a PSR-7 stream.
$body = \GuzzleHttp\Psr7\stream_for('hello!');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
</code></pre>
<p>上传JSON数据以及设置合适的头信息可以使用 <code>json</code> 请求参数这个简单的方式:</p>
<pre><code>$r = $client->request('PUT', 'http://httpbin.org/put', [
'json' => ['foo' => 'bar']
]);
</code></pre>
<h3 id="post表单请求">POST/表单请求</h3>
<p>除了使用 <code>body</code> 参数来指定请求数据外,Guzzle为发送POST数据提供了有用的方法。</p>
<h4 id="发送表单字段">发送表单字段</h4>
<p>发送 <code>application/x-www-form-urlencoded</code> POST请求需要你传入 <code>form_params</code> 数组参数,数组内指定POST的字段。</p>
<pre><code>$response = $client->request('POST', 'http://httpbin.org/post', [
'form_params' => [
'field_name' => 'abc',
'other_field' => '123',
'nested_field' => [
'nested' => 'hello'
]
]
]);
</code></pre>
<h4 id="发送表单文件">发送表单文件</h4>
<p>你可以通过使用 <code>multipart</code> 请求参数来发送表单(表单enctype属性需要设置 <code>multipart/form-data</code> )文件, 该参数接收一个包含多个关联数组的数组,每个关联数组包含一下键名:</p>
<ul>
<li>name: (必须,字符串) 映射到表单字段的名称。</li>
<li>contents: (必须,混合) 提供一个字符串,可以是 <code>fopen</code> 返回的资源、或者一个</li>
</ul>
<p><code>Psr\Http\Message\StreamInterface</code> 的实例。</p>
<pre><code>$response = $client->request('POST', 'http://httpbin.org/post', [
'multipart' => [
[
'name' => 'field_name',
'contents' => 'abc'
],
[
'name' => 'file_name',
'contents' => fopen('/path/to/file', 'r')
],
[
'name' => 'other_file',
'contents' => 'hello',
'filename' => 'filename.txt',
'headers'=> [
'X-Foo' => 'this is an extra header to include'
]
]
]
]);
</code></pre>
<h2 id="cookies">Cookies</h2>
<p>Guzzle可以使用 <code>cookies</code> 请求参数为你维护一个cookie会话,当发送一个请求时, <code>cookies</code> 选项必须设置成 <code>GuzzleHttp\Cookie\CookieJarInterface</code> 的实例。</p>
<pre><code>// Use a specific cookie jar
$jar = new \GuzzleHttp\Cookie\CookieJar;
$r = $client->request('GET', 'http://httpbin.org/cookies', [
'cookies' => $jar
]);
</code></pre>
<p>You can set <code>cookies</code> to <code>true</code> in a client constructor if you would like to use a shared cookie jar for all requests.</p>
<pre><code>// Use a shared client cookie jar
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'http://httpbin.org/cookies');
</code></pre>
<h2 id="重定向">重定向</h2>
<p>如果你没有告诉Guzzle不要重定向,Guzzle会自动的进行重定向,你可以使用 <code>allow_redirects</code> 请求参数来自定义重定向行为。</p>
<ul>
<li>设置成 <code>true</code> 时将启用最大数量为5的重定向,这是默认设置。</li>
<li>设置成 <code>false</code> 来禁用重定向。</li>
<li>传入一个包含 <code>max</code> 键名的关联数组来声明最大重定向次数,提供可选的 <code>strict</code> 键名来声明是否使用严格的RFC标准重定向 (表示使用POST请求重定向POST请求 vs 大部分浏览器使用GET请求重定向POST请求)。</li>
</ul>
<pre><code>$response = $client->request('GET', 'http://github.com');
echo $response->getStatusCode();
// 200
</code></pre>
<p>下面的列子表示重定向被禁止:</p>
<pre><code>$response = $client->request('GET', 'http://github.com', [
'allow_redirects' => false
]);
echo $response->getStatusCode();
// 301
</code></pre>
<h2 id="异常">异常</h2>
<p>请求传输过程中出现的错误Guzzle将会抛出异常。</p>
<ul>
<li>
<p>在发送网络错误(连接超时、DNS错误等)时,将会抛出 <code>GuzzleHttp\Exception\RequestException</code> 异常。 该异常继承自 <code>GuzzleHttp\Exception\TransferException</code> ,捕获这个异常可以在传输请求过程中抛出异常。</p>
<pre><code>use GuzzleHttp\Exception\RequestException;
try {
$client->request('GET', 'https://github.com/_abc_123_404');
} catch (RequestException $e) {
echo $e->getRequest();
if ($e->hasResponse()) {
echo $e->getResponse();
}
}
</code></pre>
</li>
<li>
<p><code>GuzzleHttp\Exception\ConnectException</code> 异常发生在网络错误时, 该异常继承自 <code>GuzzleHttp\Exception\RequestException</code> 。</p>
</li>
<li>
<p>如果 <code>http_errors</code> 请求参数设置成true,在400级别的错误的时候将会抛出 <code>GuzzleHttp\Exception\ClientException</code> 异常, 该异常继承自 <code>GuzzleHttp\Exception\BadResponseException</code> <code>GuzzleHttp\Exception\BadResponseException</code> 继承自 <code>GuzzleHttp\Exception\RequestException</code> 。</p>
<pre><code>use GuzzleHttp\Exception\ClientException;
try {
$client->request('GET', 'https://github.com/_abc_123_404');
} catch (ClientException $e) {
echo $e->getRequest();
echo $e->getResponse();
}
</code></pre>
</li>
<li>
<p>如果 <code>http_errors</code> 请求参数设置成true,在500级别的错误的时候将会抛出 <code>GuzzleHttp\Exception\ServerException</code> 异常。 该异常继承自 <code>GuzzleHttp\Exception\BadResponseException</code> 。</p>
</li>
<li>
<p><code>GuzzleHttp\Exception\TooManyRedirectsException</code> 异常发生在重定向次数过多时, 该异常继承自 <code>GuzzleHttp\Exception\RequestException</code> 。</p>
</li>
</ul>
<p>上述所有异常均继承自 <code>GuzzleHttp\Exception\TransferException</code> 。</p>
<h2 id="环境变量">环境变量</h2>
<p>Guzzle提供了一些可自定义的环境变量:</p>
<ul>
<li>
<p><code>GUZZLE_CURL_SELECT_TIMEOUT</code></p>
<p>当在curl处理器时使用 <code>curl_multi_select()</code> 控制了 curl_multi_* 需要使用到的持续时间, 有些系统实现PHP的 <code>curl_multi_select()</code> 存在问题,调用该函数时总是等待超时的最大值。</p>
</li>
<li>
<p><code>HTTP_PROXY</code></p>
<p>定义了使用http协议发送请求时使用的代理。</p>
</li>
<li>
<p><code>HTTPS_PROXY</code></p>
<p>定义了使用https协议发送请求时使用的代理。</p>
</li>
</ul>
<h3 id="相关ini设置">相关ini设置</h3>
<p>Guzzle配置客户端时可以利用PHP的ini配置。</p>
<ul>
<li>
<p><code>openssl.cafile</code></p>
<p>当发送到"https"协议的请求时需要用到指定磁盘上PEM格式的CA文件,参考: https://wiki.php.net/rfc/tls-peer-verification#phpini_defaults</p>
</li>
</ul>
<h2 id="请求选项">请求选项</h2>
<p>你可以通过设置Client的 <strong>请求选项</strong> 来自定义请求,请求参数控制请求的各个方面,包括头信息、查询字符串参数、超时、请求主体等。</p>
<p>下述所有的列子都使用下面的Client:</p>
<pre><code>$client = new GuzzleHttp\Client(['base_uri' => 'http://httpbin.org']);
</code></pre>
<h3 id="allow_redirects">allow_redirects</h3>
<ul>
<li>
<p>摘要</p>
<p>描述请求的重定向行为</p>
</li>
<li>
<p>类型</p>
<p>boolarray</p>
</li>
<li>
<p>默认值</p>
<pre><code>[
'max' => 5,
'strict' => false,
'referer' => true,
'protocols' => ['http', 'https'],
'track_redirects' => false
]
</code></pre>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::ALLOW_REDIRECTS</code></p>
</li>
</ul>
<p>设置成 <code>false</code> 禁用重定向。</p>
<pre><code>$res = $client->request('GET', '/redirect/3', ['allow_redirects' => false]);
echo $res->getStatusCode();
// 302
</code></pre>
<p>设置成 <code>true</code> (默认设置) 来启用默认最大次数为5的重定向。</p>
<pre><code>$res = $client->request('GET', '/redirect/3');
echo $res->getStatusCode();
// 200
</code></pre>
<p>你也可以传送一个包含了以下键值对的关联数组:</p>
<ul>
<li>max: (int, 默认为5) 允许重定向次数的最大值。</li>
<li>strict: (bool, 默认为false) 设置成 true 使用严格模式重定向 严格RFC模式重定向表示使用POST请求重定向POST请求 vs 大部分浏览器使用GET请求重定向POST请求。</li>
<li>referer: (bool, 默认为true) 设置成 false 重定向时禁止添加Refer头信息。</li>
<li>protocols: (array, 默认为['http', 'https']) 指定允许重定向的协议。</li>
<li>on_redirect: (callable) 发生重定向时调用PHP回调,包含了原始的请求以及接收到重定向的响应,on_redirect的任何返回将会被忽略。</li>
<li>track_redirects: (bool) 当设置成 <code>true</code> 时,每个重定向的URI将会按序被跟踪头信息 <code>X-Guzzle-Redirect-History</code> 。</li>
</ul>
<pre><code>use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UriInterface;
$onRedirect = function(
RequestInterface $request,
ResponseInterface $response,
UriInterface $uri
) {
echo 'Redirecting! ' . $request->getUri() . ' to ' . $uri . "\n";
};
$res = $client->request('GET', '/redirect/3', [
'allow_redirects' => [
'max' => 10, // allow at most 10 redirects.
'strict' => true, // use "strict" RFC compliant redirects.
'referer' => true, // add a Referer header
'protocols' => ['https'], // only allow https URLs
'on_redirect' => $onRedirect,
'track_redirects' => true
]
]);
echo $res->getStatusCode();
// 200
echo $res->getHeaderLine('X-Guzzle-Redirect-History');
// http://first-redirect, http://second-redirect, etc...
</code></pre>
<h3 id="auth">auth</h3>
<ul>
<li>
<p>摘要</p>
<p>传入HTTP认证参数的数组来使用请求,该数组索引为用户名、索引为密码,索引为可选的内置认证类型。传入 <code>null</code> 进入请求认证。</p>
</li>
<li>
<p>类型</p>
<p>arraystringnull</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::AUTH</code></p>
</li>
</ul>
<p>内置认证类型如下:</p>
<ul>
<li>
<p>basic</p>
<p>在 <code>Authorization</code> 头信息使用 HTTP基础认证 (如果没有指定的话为默认设置)。</p>
</li>
</ul>
<pre><code>$client->request('GET', '/get', ['auth' => ['username', 'password']]);
</code></pre>
<ul>
<li>
<p>digest</p>
<p>使用 摘要式认证 (必须被HTTP处理器支持)。</p>
</li>
</ul>
<pre><code>$client->request('GET', '/get', [
'auth' => ['username', 'password', 'digest']
]);
</code></pre>
<h3 id="body">body</h3>
<ul>
<li>
<p>摘要</p>
<p><code>body</code> 选项用来控制一个请求(比如:PUT, POST, PATCH)的主体部分。</p>
</li>
<li>
<p>类型</p>
<p>string<code>fopen()</code> resource<code>Psr\Http\Message\StreamInterface</code></p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::BODY</code></p>
</li>
</ul>
<p>可以设置成下述类型:</p>
<ul>
<li>
<p>string</p>
<pre><code>// You can send requests that use a string as the message body.
$client->request('PUT', '/put', ['body' => 'foo']);
</code></pre>
</li>
<li>
<p>resource returned from <code>fopen()</code></p>
<pre><code>// You can send requests that use a stream resource as the body.
$resource = fopen('http://httpbin.org', 'r');
$client->request('PUT', '/put', ['body' => $resource]);
</code></pre>
</li>
<li>
<p><code>Psr\Http\Message\StreamInterface</code></p>
<pre><code>// You can send requests that use a Guzzle stream object as the body
$stream = GuzzleHttp\Psr7\stream_for('contents...');
$client->request('POST', '/post', ['body' => $stream]);
</code></pre>
</li>
</ul>
<h3 id="cert">cert</h3>
<ul>
<li>
<p>摘要</p>
<p>设置成指定PEM格式认证文件的路径的字符串,如果需要密码,需要设置成一个数组,其中PEM文件在第一个元素,密码在第二个元素。</p>
</li>
<li>
<p>类型</p>
<p>stringarray</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::CERT</code></p>
</li>
</ul>
<pre><code>$client->request('GET', '/', ['cert' => ['/path/server.pem', 'password']]);
</code></pre>
<h3 id="cookies-1">cookies</h3>
<ul>
<li>
<p>摘要</p>
<p>声明是否在请求中使用cookie,或者要使用的cookie jar,或者要发送的cookie。</p>
</li>
<li>
<p>类型</p>
<p><code>GuzzleHttp\Cookie\CookieJarInterface</code></p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::COOKIES</code></p>
</li>
</ul>
<p>你必须声明cookie选项为 <code>GuzzleHttp\Cookie\CookieJarInterface</code> 或 <code>false</code> 。</p>
<pre><code>$jar = new \GuzzleHttp\Cookie\CookieJar();
$client->request('GET', '/get', ['cookies' => $jar]);
</code></pre>
<h3 id="connect_timeout">connect_timeout</h3>
<ul>
<li>
<p>摘要</p>
<p>表示等待服务器响应超时的最大值,使用 <code>0</code> 将无限等待 (默认行为).</p>
</li>
<li>
<p>类型</p>
<p>float</p>
</li>
<li>
<p>默认值</p>
<p><code>0</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::CONNECT_TIMEOUT</code></p>
</li>
</ul>
<pre><code>// Timeout if the client fails to connect to the server in 3.14 seconds.
$client->request('GET', '/delay/5', ['connect_timeout' => 3.14]);
</code></pre>
<h3 id="debug">debug</h3>
<ul>
<li>
<p>摘要</p>
<p>设置成 <code>true</code> 或设置成一个 <code>fopen()</code> 返回的流来启用调试输出发送请求的处理器, 比如,当使用cURL传输请求,cURL的 <code>CURLOPT_VERBOSE</code> 的冗长将会发出, 当使用PHP流,流处理的提示将会发生。 如果设置为true,输出到PHP标准输出文件,如果提供了PHP流,将会输出到流。</p>
</li>
<li>
<p>类型</p>
<p>bool<code>fopen()</code> resource</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::DEBUG</code></p>
</li>
</ul>
<pre><code>$client->request('GET', '/get', ['debug' => true]);
</code></pre>
<p>执行上面的例子将会输出类似下面的结果:</p>
<pre><code>* About to connect() to httpbin.org port 80 (#0)
* Trying 107.21.213.98... * Connected to httpbin.org (107.21.213.98) port 80 (#0)
> GET /get HTTP/1.1
Host: httpbin.org
User-Agent: Guzzle/4.0 curl/7.21.4 PHP/5.5.7
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Type: application/json
< Date: Sun, 16 Feb 2014 06:50:09 GMT
< Server: gunicorn/0.17.4
< Content-Length: 335
< Connection: keep-alive
<
* Connection #0 to host httpbin.org left intact
</code></pre>
<h3 id="decode_content">decode_content</h3>
<ul>
<li>
<p>摘要</p>
<p>声明是否自动解码 <code>Content-Encoding</code> 响应 (gzip, deflate等) 。</p>
</li>
<li>
<p>类型</p>
<p>stringbool</p>
</li>
<li>
<p>默认值</p>
<p><code>true</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::DECODE_CONTENT</code></p>
</li>
</ul>
<p>该选项可以用来控制Content-Encoding如何响应主体的,默认 <code>decode_content</code> 设置为 true,表示Guzzle将自动解码gzip,deflate等响应。</p>
<p>当设置成 <code>false</code> ,响应的主体将不会被解码,意味着字节将毫无变化的通过处理器。</p>
<pre><code>// Request gzipped data, but do not decode it while downloading
$client->request('GET', '/foo.js', [
'headers' => ['Accept-Encoding' => 'gzip'],
'decode_content' => false
]);
</code></pre>
<p>当设置成字符串,响应的字节将被解码,提供 <code>decode_content</code> 选项的字符串将作为请求的 <code>Accept-Encoding</code> 报文头。</p>
<pre><code>// Pass "gzip" as the Accept-Encoding header.
$client->request('GET', '/foo.js', ['decode_content' => 'gzip']);
</code></pre>
<h3 id="delay">delay</h3>
<ul>
<li>
<p>摘要</p>
<p>发送请求前延迟的毫秒数值</p>
</li>
<li>
<p>类型</p>
<p>integerfloat</p>
</li>
<li>
<p>默认值</p>
<p>null</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::DELAY</code></p>
</li>
</ul>
<h3 id="expect">expect</h3>
<ul>
<li>
<p>摘要</p>
<p>控制"Expect: 100-Continue"报文头的行为。</p>
</li>
<li>
<p>类型</p>
<p>boolinteger</p>
</li>
<li>
<p>默认值</p>
<p><code>1048576</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::EXPECT</code></p>
</li>
</ul>
<p>设置成 <code>true</code> 来为所有发送主体的请求启用 "Expect: 100-Continue" 报文头; 设置成 <code>false</code> 来为所有的请求禁用 "Expect: 100-Continue" 报文头; 设置成一个数值,有效载荷的大小必须大于预计发送的值,设置成数值将会为所有不确定有效载荷大小或主体不能确定指针位置的请求发送Expect报文头,</p>
<p>默认情况下,当请求的主体大于1MB以及请求使用的HTTP/1.1,Guzzle将会添加 "Expect: 100-Continue" 报文头。</p>
<h3 id="form_params">form_params</h3>
<ul>
<li>
<p>摘要</p>
<p>用来发送一个 application/x-www-form-urlencoded POST请求.</p>
</li>
<li>
<p>类型</p>
<p>array</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::FORM_PARAMS</code></p>
</li>
</ul>
<p>关联数组由表单字段键值对构成,每个字段值可以是一个字符串或一个包含字符串元素的数组。 当没有准备 "Content-Type" 报文头的时候,将设置为 "application/x-www-form-urlencoded"。</p>
<pre><code>$client->request('POST', '/post', [
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there!']
]
]);
</code></pre>
<h3 id="headers">headers</h3>
<ul>
<li>
<p>摘要</p>
<p>要添加到请求的报文头的关联数组,每个键名是header的名称,每个键值是一个字符串或包含代表头字段字符串的数组。</p>
</li>
<li>
<p>类型</p>
<p>array</p>
</li>
<li>
<p>Defaults</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::HEADERS</code></p>
</li>
</ul>
<pre><code>// Set various headers on a request
$client->request('GET', '/get', [
'headers' => [
'User-Agent' => 'testing/1.0',
'Accept' => 'application/json',
'X-Foo' => ['Bar', 'Baz']
]
]);
</code></pre>
<p>创建Client的时候头信息可以作为默认选项添加,当头信息使用默认选项时,它们只能在请求没有包含特殊头信息的时候生效, 这包括了Client的 <code>send()</code> 与 <code>sendAsync()</code> 方法,以及Client创建的请求(比如 <code>request()</code> 与 <code>requestAsync()</code>)。</p>
<pre><code>$client = new GuzzleHttp\Client(['headers' => ['X-Foo' => 'Bar']]);
// Will send a request with the X-Foo header.
$client->request('GET', '/get');
// Sets the X-Foo header to "test", which prevents the default header
// from being applied.
$client->request('GET', '/get', ['headers' => ['X-Foo' => 'test']);
// Will disable adding in default headers.
$client->request('GET', '/get', ['headers' => null]);
// Will not overwrite the X-Foo header because it is in the message.
use GuzzleHttp\Psr7\Request;
$request = new Request('GET', 'http://foo.com', ['X-Foo' => 'test']);
$client->send($request);
// Will overwrite the X-Foo header with the request option provided in the
// send method.
use GuzzleHttp\Psr7\Request;
$request = new Request('GET', 'http://foo.com', ['X-Foo' => 'test']);
$client->send($request, ['headers' => ['X-Foo' => 'overwrite']]);
</code></pre>
<h3 id="http_errors">http_errors</h3>
<ul>
<li>
<p>摘要</p>
<p>设置成 <code>false</code> 来禁用HTTP协议抛出的异常(如 4xx 和 5xx 响应),默认情况下HTPP协议出错时会抛出异常。</p>
</li>
<li>
<p>类型</p>
<p>bool</p>
</li>
<li>
<p>默认值</p>
<p><code>true</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::HTTP_ERRORS</code></p>
</li>
</ul>
<pre><code>$client->request('GET', '/status/500');
// Throws a GuzzleHttp\Exception\ServerException
$res = $client->request('GET', '/status/500', ['http_errors' => false]);
echo $res->getStatusCode();
// 500
</code></pre>
<h3 id="json">json</h3>
<ul>
<li>
<p>摘要</p>
<p><code>json</code> 选项用来轻松将JSON数据当成主体上传, 如果没有设置Content-Type头信息的时候会设置成 <code>application/json</code> 。</p>
</li>
<li>
<p>类型</p>
<p>能够 <code>json_encode()</code> 操作的PHP类型。</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::JSON</code></p>
</li>
</ul>
<pre><code>$response = $client->request('PUT', '/put', ['json' => ['foo' => 'bar']]);
</code></pre>
<p>这里的例子使用了 <code>tap</code> 中间件用来查看发送了什么请求。</p>
<pre><code>use GuzzleHttp\Middleware;
// Grab the client's handler instance.
$clientHandler = $client->getConfig('handler');
// Create a middleware that echoes parts of the request.
$tapMiddleware = Middleware::tap(function ($request) {
echo $request->getHeader('Content-Type');
// application/json
echo $request->getBody();
// {"foo":"bar"}
});
$response = $client->request('PUT', '/put', [
'json' => ['foo' => 'bar'],
'handler' => $tapMiddleware($clientHandler)
]);
</code></pre>
<h3 id="multipart">multipart</h3>
<ul>
<li>
<p>摘要</p>
<p>设置请求的主体为 multipart/form-data 表单。</p>
</li>
<li>
<p>类型</p>
<p>array</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::MULTIPART</code></p>
</li>
</ul>
<p><code>multipart</code> 的值是一个关联数组,每个元素包含以下键值对:</p>
<ul>
<li><code>name</code>: (string, required) 表单字段名称</li>
<li><code>contents</code>: (StreamInterface/resource/string, required) 表单元素中要使用的数据</li>
<li><code>headers</code>: (array) 可选的表单元素要使用的键值对数组</li>
<li><code>filename</code>: (string) 可选的作为要发送的文件名称</li>
</ul>
<pre><code>$client->request('POST', '/post', [
'multipart' => [
[
'name' => 'foo',
'contents' => 'data',
'headers'=> ['X-Baz' => 'bar']
],
[
'name' => 'baz',
'contents' => fopen('/path/to/file', 'r')
],
[
'name' => 'qux',
'contents' => fopen('/path/to/file', 'r'),
'filename' => 'custom_filename.txt'
],
]
]);
</code></pre>
<h3 id="on_headers">on_headers</h3>
<ul>
<li>
<p>摘要</p>
<p>回调函数,当响应的HTTP头信息被接收且主体部分还未开始下载的时候调用。</p>
</li>
<li>
<p>类型</p>
<p>callable</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::ON_HEADERS</code></p>
</li>
</ul>
<p>该回调接收 <code>Psr\Http\ResponseInterface</code> 对象。 如果该回调抛出异常,与响应相关的Promise将会接收到 <code>GuzzleHttp\Exception\RequestException</code> 抛出的异常。</p>
<p>在数据写入下游之前,你应该需要知道接收到的头信息与状态码。</p>
<pre><code>// Reject responses that are greater than 1024 bytes.
$client->request('GET', 'http://httpbin.org/stream/1024', [
'on_headers' => function (ResponseInterface $response) {
if ($response->getHeaderLine('Content-Length') > 1024) {
throw new \Exception('The file is too big!');
}
}
]);
</code></pre>
<h3 id="on_stats">on_stats</h3>
<ul>
<li>
<p>摘要</p>
<p><code>on_stats</code> 允许你获取请求传输数据统计以及处理器在底层传输的详情. <code>on_stats</code> 是个回调,当处理器完成传输一个请求的时候被调用。 该回调被调用请求传输数据统计、接收到响应,或遇到错误,包含发送请求数据时间的总量。</p>
</li>
<li>
<p>类型</p>
<p>callable</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::ON_STATS</code></p>
</li>
</ul>
<p>该回调接收 <code>GuzzleHttp\TransferStats</code> 对象。</p>
<pre><code>use GuzzleHttp\TransferStats;
$client = new GuzzleHttp\Client();
$client->request('GET', 'http://httpbin.org/stream/1024', [
'on_stats' => function (TransferStats $stats) {
echo $stats->getEffectiveUri() . "\n";
echo $stats->getTransferTime() . "\n";
var_dump($stats->getHandlerStats());
// You must check if a response was received before using the
// response object.
if ($stats->hasResponse()) {
echo $stats->getResponse()->getStatusCode();
} else {
// Error data is handler specific. You will need to know what
// type of error data your handler uses before using this
// value.
var_dump($stats->getHandlerErrorData());
}
}
]);
</code></pre>
<h3 id="proxy">proxy</h3>
<ul>
<li>
<p>摘要</p>
<p>传入字符串来指定HTTP代理,或者为不同代理指定不同协议的数组。</p>
</li>
<li>
<p>类型</p>
<p>stringarray</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::PROXY</code></p>
</li>
</ul>
<p>传入字符串为所有协议指定一个代理:</p>
<pre><code>$client->request('GET', '/', ['proxy' => 'tcp://localhost:8125']);
</code></pre>
<p>传入关联数组来为特殊的URI Scheme指定特色的HTTP代理(比如"http", "https") 提供一个 <code>no</code> 键值对来提供一组不需要使用代理的主机名。</p>
<pre><code>$client->request('GET', '/', [
'proxy' => [
'http'=> 'tcp://localhost:8125', // Use this proxy with "http"
'https' => 'tcp://localhost:9124', // Use this proxy with "https",
'no' => ['.mit.edu', 'foo.com'] // Don't use a proxy with these
]
]);
</code></pre>
<h3 id="query">query</h3>
<ul>
<li>
<p>摘要</p>
<p>要添加到请求的查询字符串的关联数组或查询字符串。</p>
</li>
<li>
<p>类型</p>
<p>arraystring</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::QUERY</code></p>
</li>
</ul>
<pre><code>// Send a GET request to /get?foo=bar
$client->request('GET', '/get', ['query' => ['foo' => 'bar']]);
</code></pre>
<p>在 <code>query</code> 选项查询字符串指定,将会覆盖在请求时提供的查询字符串值。</p>
<pre><code>// Send a GET request to /get?foo=bar
$client->request('GET', '/get?abc=123', ['query' => ['foo' => 'bar']]);
</code></pre>
<h3 id="sink">sink</h3>
<ul>
<li>
<p>摘要</p>
<p>声明响应的主体部分将要保存的位置。</p>
</li>
<li>
<p>类型</p>
<p>string (path to file on disk)<code>fopen()</code> resource<code>Psr\Http\Message\StreamInterface</code></p>
</li>
<li>
<p>默认值</p>
<p>PHP temp stream</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::SINK</code></p>
</li>
</ul>
<p>传入字符串来指定将要保存响应主体内容的文件的路径:</p>
<pre><code>$client->request('GET', '/stream/20', ['sink' => '/path/to/file']);
</code></pre>
<p>传入 <code>fopen()</code> 返回的资源将响应写入PHP流:</p>
<pre><code>$resource = fopen('/path/to/file', 'w');
$client->request('GET', '/stream/20', ['sink' => $resource]);
</code></pre>
<p>传入 <code>Psr\Http\Message\StreamInterface</code> 对象将响应写入打开的PSR-7流。</p>
<pre><code>$resource = fopen('/path/to/file', 'w');
$stream = GuzzleHttp\Psr7\stream_for($resource);
$client->request('GET', '/stream/20', ['save_to' => $stream]);
</code></pre>
<h3 id="ssl_key">ssl_key</h3>
<ul>
<li>
<p>摘要</p>
<p>指定一个链接到私有SSL密钥的PEM格式的文件的路径的字符串。 如果需要密码,设置成一个数组,数组第一个元素为链接到私有SSL密钥的PEM格式的文件的路径,第二个元素为认证密码。</p>
</li>
<li>
<p>类型</p>
<p>stringarray</p>
</li>
<li>
<p>默认值</p>
<p>None</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::SSL_KEY</code></p>
</li>
</ul>
<h3 id="stream">stream</h3>
<ul>
<li>
<p>摘要</p>
<p>设置成 <code>true</code> 流响应,而非下载响应。</p>
</li>
<li>
<p>类型</p>
<p>bool</p>
</li>
<li>
<p>默认值</p>
<p><code>false</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::STREAM</code></p>
</li>
</ul>
<pre><code>$response = $client->request('GET', '/stream/20', ['stream' => true]);
// Read bytes off of the stream until the end of the stream is reached
$body = $response->getBody();
while (!$body->eof()) {
echo $body->read(1024);
}
</code></pre>
<h3 id="synchronous">synchronous</h3>
<ul>
<li>
<p>摘要</p>
<p>设置成 true 来通知HTTP处理器你要等待响应,这有利于优化。</p>
</li>
<li>
<p>类型</p>
<p>bool</p>
</li>
<li>
<p>默认值</p>
<p>none</p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::SYNCHRONOUS</code></p>
</li>
</ul>
<h3 id="verify">verify</h3>
<ul>
<li>
<p>摘要</p>
<p>请求时验证SSL证书行为。设置成 <code>true</code> 启用SSL证书验证,默认使用操作系统提供的CA包。设置成 <code>false</code> 禁用证书验证(这是不安全的!)。设置成字符串启用验证,并使用该字符串作为自定义证书CA包的路径。</p>
</li>
<li>
<p>类型</p>
<p>boolstring</p>
</li>
<li>
<p>默认值</p>
<p><code>true</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::VERIFY</code></p>
</li>
</ul>
<pre><code>// Use the system's CA bundle (this is 默认设置)
$client->request('GET', '/', ['verify' => true]);
// Use a custom SSL certificate on disk.
$client->request('GET', '/', ['verify' => '/path/to/cert.pem']);
// Disable validation entirely (don't do this!).
$client->request('GET', '/', ['verify' => false]);
</code></pre>
<p>并非所有的系统磁盘上都存在CA包,比如,Windows和OS X并没有通用的本地CA包。 当设置"verify" 为 <code>true</code> 时,Guzzle将尽力在你的操作系统中找到合适的CA包, 当使用cURL或PHP 5.6以上版本的流时,Guzzle将按以下顺序尝试查找CA包:</p>
<ol>
<li>检查php.ini文件中是否设置了 <code>openssl.cafile</code> 。</li>
<li>检查php.ini文件中是否设置了 <code>curl.cainfo</code> 。</li>
<li>检查 <code>/etc/pki/tls/certs/ca-bundle.crt</code> 是否存在 (Red Hat, CentOS, Fedora; 由ca-certificates包提供)</li>
<li>检查 <code>/etc/ssl/certs/ca-certificates.crt</code> 是否存在 (Ubuntu, Debian; 由ca-certificates包提供)</li>
<li>检查 <code>/usr/local/share/certs/ca-root-nss.crt</code> 是否存在 (FreeBSD; 由ca_root_nss包提供)</li>
<li>检查 <code>/usr/local/etc/openssl/cert.pem</code> 是否存在 (OS X; 由homebrew提供)</li>
<li>检查 <code>C:\windows\system32\curl-ca-bundle.crt</code> 是否存在 (Windows)</li>
<li>检查 <code>C:\windows\curl-ca-bundle.crt</code> 是否存在 (Windows)</li>
</ol>
<p>查询的结果将缓存在内存中,以便同一进程后续快速调用。 然而在有些服务器如Apache中每个请求都在独立的进程中,你应该考虑设置 <code>openssl.cafile</code> 环境变量,指定到磁盘文件,以便整个过程都跳过。</p>
<p>如果你不需要特殊的证书包,可以使用Mozilla提供的通用CA包,你可以在 这里 下载(由cURL的维护者提供)。 一旦磁盘有了CA包,你可以设置PHP ini配置文件,指定该文件的路径到变量 <code>openssl.cafile</code> 中,这样就可以在请求中省略 "verify" 参数。 你可以在 cURL 网站 发现更多关于SSL证书的细节。</p>
<h3 id="timeout">timeout</h3>
<ul>
<li>
<p>摘要</p>
<p>请求超时的秒数。使用 <code>0</code> 无限期的等待(默认行为)。</p>
</li>
<li>
<p>类型</p>
<p>float</p>
</li>
<li>
<p>默认值</p>
<p><code>0</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::TIMEOUT</code></p>
</li>
</ul>
<pre><code>// Timeout if a server does not return a response in 3.14 seconds.
$client->request('GET', '/delay/5', ['timeout' => 3.14]);
// PHP Fatal error:Uncaught exception 'GuzzleHttp\Exception\RequestException'
</code></pre>
<h3 id="version">version</h3>
<ul>
<li>
<p>摘要</p>
<p>请求要使用到的协议版本。</p>
</li>
<li>
<p>类型</p>
<p>string, float</p>
</li>
<li>
<p>默认值</p>
<p><code>1.1</code></p>
</li>
<li>
<p>常量</p>
<p><code>GuzzleHttp\RequestOptions::VERSION</code></p>
</li>
</ul>
<pre><code>// Force HTTP/1.0
$request = $client->request('GET', '/get', ['version' => 1.0]);
</code></pre><br><br>
来源:https://www.cnblogs.com/makalochen/p/13558570.html
頁:
[1]