composer require guzzlehttp/guzzle<?php
require_once 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
// 创建客户端实例
$client = new Client([
'base_uri' => 'https://api.example.com',
'timeout' => 30,
]);
try {
// 简单 GET 请求
$response = $client->get('/users');
echo $response->getStatusCode(); // 200
echo $response->getBody(); // 响应体内容
// 带查询参数的 GET 请求
$response = $client->get('/users', [
'query' => [
'page' => 1,
'limit' => 10,
'sort' => 'name'
]
]);
} catch (RequestException $e) {
echo "请求失败: " . $e->getMessage();
}<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client();
// JSON POST 请求
$response = $client->post('https://api.example.com/users', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer your-token',
'User-Agent' => 'MyApp/1.0'
],
'json' => [
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => 30
],
'timeout' => 30
]);
// 表单 POST 请求
$response = $client->post('https://api.example.com/login', [
'form_params' => [
'username' => 'john',
'password' => 'secret'
]
]);
// 多部分表单数据(文件上传)
$response = $client->post('https://api.example.com/upload', [
'multipart' => [
[
'name' => 'file',
'contents' => fopen('/path/to/file.jpg', 'r'),
'filename' => 'photo.jpg'
],
[
'name' => 'description',
'contents' => 'Profile photo'
]
]
]);<?php
// PUT 请求 - 更新资源
$response = $client->put('https://api.example.com/users/123', [
'json' => [
'name' => 'Jane Doe',
'email' => 'jane@example.com'
]
]);
// PATCH 请求 - 部分更新
$response = $client->patch('https://api.example.com/users/123', [
'json' => [
'email' => 'new-email@example.com'
]
]);
// DELETE 请求
$response = $client->delete('https://api.example.com/users/123');<?php
$client = new Client([
// 基础URI
'base_uri' => 'https://api.example.com/api/v1/',
// 超时设置
'timeout' => 30.0,
'connect_timeout' => 10.0,
'read_timeout' => 30.0,
// SSL 配置
'verify' => true, // 或 false 跳过SSL验证
'cert' => '/path/to/cert.pem',
'ssl_key' => '/path/to/private-key.pem',
// 代理设置
'proxy' => [
'http' => 'tcp://localhost:8125',
'https' => 'tcp://localhost:9124'
],
// 重定向设置
'allow_redirects' => [
'max' => 5,
'strict' => false,
'referer' => true,
'protocols' => ['http', 'https'],
'track_redirects' => false
],
// Cookie 处理
'cookies' => true,
// 调试模式
'debug' => true,
// 默认头信息
'headers' => [
'User-Agent' => 'MyApp/1.0',
'Accept' => 'application/json',
],
// HTTP 认证
'auth' => ['username', 'password', 'basic|digest|ntlm'],
]);<?php
$response = $client->request('POST', '/endpoint', [
// 查询参数
'query' => ['key' => 'value'],
// 请求头
'headers' => [
'X-Custom-Header' => 'value',
'Authorization' => 'Bearer token'
],
// JSON 数据
'json' => ['key' => 'value'],
// 表单数据
'form_params' => ['key' => 'value'],
// 多部分数据
'multipart' => [
['name' => 'field', 'contents' => 'value']
],
// 原始 body
'body' => 'raw data',
// 超时设置
'timeout' => 30,
'connect_timeout' => 10,
// SSL 验证
'verify' => false,
// 代理
'proxy' => 'http://proxy:8080',
// 重定向
'allow_redirects' => false,
// 异常处理
'http_errors' => false, // 不抛出HTTP错误异常
// 查询参数
'query' => http_build_query([
'page' => 1,
'limit' => 20
]),
// 自定义域名解析
'force_ip_resolve' => 'v4', // 或 'v6'
]);<?php
$response = $client->get('https://api.example.com/users');
// 获取状态码
$statusCode = $response->getStatusCode(); // 200
// 获取响应头
$contentType = $response->getHeader('Content-Type')[0];
$allHeaders = $response->getHeaders();
// 获取响应体
$body = (string) $response->getBody();
// JSON 响应处理
$data = json_decode($body, true);
// 流式读取大响应
$body = $response->getBody();
while (!$body->eof()) {
echo $body->read(1024);
}
// 保存到文件
$file = fopen('/path/to/file', 'w');
while (!$body->eof()) {
fwrite($file, $body->read(1024));
}
fclose($file);<?php
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\TransferException;
try {
$response = $client->get('https://api.example.com/data');
} catch (ConnectException $e) {
// 连接异常(网络问题)
echo "连接失败: " . $e->getMessage();
} catch (RequestException $e) {
// 请求异常(HTTP 4xx/5xx 响应)
if ($e->hasResponse()) {
$response = $e->getResponse();
$statusCode = $response->getStatusCode();
$errorBody = (string) $response->getBody();
echo "HTTP错误 {$statusCode}: {$errorBody}";
} else {
echo "请求异常: " . $e->getMessage();
}
} catch (TransferException $e) {
// 其他传输异常
echo "传输异常: " . $e->getMessage();
} catch (\Exception $e) {
// 其他异常
echo "未知异常: " . $e->getMessage();
}<?php
use GuzzleHttp\Promise;
use GuzzleHttp\Psr7\Response;
// 单个异步请求
$promise = $client->getAsync('https://api.example.com/users');
$promise->then(
function (Response $response) {
echo "成功: " . $response->getStatusCode();
},
function (RequestException $e) {
echo "失败: " . $e->getMessage();
}
);
// 等待异步请求完成
$response = $promise->wait();
// 批量异步请求
$promises = [
'users' => $client->getAsync('/users'),
'posts' => $client->getAsync('/posts'),
'comments' => $client->getAsync('/comments')
];
// 等待所有请求完成
$results = Promise\Utils::unwrap($promises);
// 或者使用 settle(不抛出异常)
$results = Promise\Utils::settle($promises)->wait();
foreach ($results as $key => $result) {
if ($result['state'] === 'fulfilled') {
echo "{$key}: 成功\n";
} else {
echo "{$key}: 失败 - " . $result['reason']->getMessage() . "\n";
}
}<?php
// 链式异步操作
$promise = $client->getAsync('/users')
->then(function ($response) use ($client) {
// 第一个请求成功后执行第二个请求
$data = json_decode($response->getBody(), true);
$userId = $data['users'][0]['id'];
return $client->getAsync("/users/{$userId}");
})
->then(function ($response) {
// 处理最终结果
$userData = json_decode($response->getBody(), true);
return $userData;
})
->otherwise(function ($exception) {
// 错误处理
echo "请求失败: " . $exception->getMessage();
return null;
});
$result = $promise->wait();<?php
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
// 创建处理器栈
$stack = HandlerStack::create();
// 添加日志中间件
$stack->push(Middleware::log(
new \Monolog\Logger('HTTP'),
new \GuzzleHttp\MessageFormatter('{method} {uri} HTTP/{version} {req_body} - {code} {res_body}')
));
// 添加重试中间件
$stack->push(Middleware::retry(function(
$retries,
RequestInterface $request,
$response = null,
$exception = null
) {
// 最大重试次数
if ($retries >= 3) {
return false;
}
// 只在服务器错误时重试
if ($response && $response->getStatusCode() >= 500) {
return true;
}
// 在超时时重试
if ($exception instanceof ConnectException) {
return true;
}
return false;
}));
// 添加认证中间件
$stack->push(function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
// 添加认证头
$request = $request->withHeader('Authorization', 'Bearer token');
return $handler($request, $options);
};
});
// 使用自定义处理器栈
$client = new Client(['handler' => $stack]);<?php
namespace App\Services;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Log\LoggerInterface;
class ApiClient
{
private Client $client;
private string $baseUrl;
private string $apiKey;
public function __construct(
string $baseUrl,
string $apiKey,
LoggerInterface $logger = null
) {
$this->baseUrl = rtrim($baseUrl, '/');
$this->apiKey = $apiKey;
$stack = HandlerStack::create();
// 添加重试中间件
$stack->push(Middleware::retry(
$this->getRetryDecider(),
$this->getRetryDelay()
));
// 添加日志中间件
if ($logger) {
$stack->push(Middleware::log(
$logger,
new \GuzzleHttp\MessageFormatter('{method} {uri} - {code}')
));
}
$this->client = new Client([
'base_uri' => $this->baseUrl,
'handler' => $stack,
'headers' => [
'User-Agent' => 'MyApiClient/1.0',
'Accept' => 'application/json',
],
'timeout' => 30,
'connect_timeout' => 10,
]);
}
public function getUsers(array $params = []): array
{
return $this->request('GET', '/users', [
'query' => $params
]);
}
public function createUser(array $data): array
{
return $this->request('POST', '/users', [
'json' => $data
]);
}
public function updateUser(int $userId, array $data): array
{
return $this->request('PUT', "/users/{$userId}", [
'json' => $data
]);
}
public function deleteUser(int $userId): bool
{
$this->request('DELETE', "/users/{$userId}");
return true;
}
private function request(string $method, string $endpoint, array $options = []): array
{
try {
// 添加认证头
$options['headers'] = array_merge(
$options['headers'] ?? [],
['Authorization' => 'Bearer ' . $this->apiKey]
);
$response = $this->client->request($method, $endpoint, $options);
$data = json_decode((string)$response->getBody(), true);
return $data['data'] ?? $data;
} catch (RequestException $e) {
if ($e->hasResponse()) {
$errorData = json_decode((string)$e->getResponse()->getBody(), true);
throw new \RuntimeException($errorData['message'] ?? 'API请求失败');
}
throw new \RuntimeException('网络请求失败: ' . $e->getMessage());
}
}
private function getRetryDecider(): callable
{
return function(
$retries,
$request,
$response = null,
$exception = null
) {
if ($retries >= 3) {
return false;
}
if ($exception instanceof ConnectException) {
return true;
}
if ($response) {
if ($response->getStatusCode() >= 500) {
return true;
}
}
return false;
};
}
private function getRetryDelay(): callable
{
return function($numberOfRetries) {
return 1000 * $numberOfRetries; // 毫秒
};
}
}<?php
// 使用 API 客户端
$apiClient = new ApiClient('https://api.example.com', 'your-api-key');
try {
// 获取用户列表
$users = $apiClient->getUsers(['page' => 1, 'limit' => 10]);
// 创建新用户
$newUser = $apiClient->createUser([
'name' => 'John Doe',
'email' => 'john@example.com'
]);
// 更新用户
$apiClient->updateUser(123, ['email' => 'new@example.com']);
// 删除用户
$apiClient->deleteUser(123);
} catch (\Exception $e) {
echo "API调用失败: " . $e->getMessage();
}<?php
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
// 创建模拟响应
$mock = new MockHandler([
new Response(200, ['Content-Type' => 'application/json'], json_encode(['data' => ['id' => 1, 'name' => 'John']])),
new Response(404, [], 'Not Found'),
new Response(500, [], 'Server Error')
]);
$handlerStack = HandlerStack::create($mock);
$client = new Client(['handler' => $handlerStack]);
// 测试
$response = $client->get('/users/1');
echo $response->getStatusCode(); // 200
$response = $client->get('/users/999');
echo $response->getStatusCode(); // 404这个完整的教程涵盖了 Guzzle HTTP 客户端的各个方面,从基础使用到高级功能,应该能满足你的所有需求!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。