首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >PHP的Guzzle HTTP 客户端快速上手教程

PHP的Guzzle HTTP 客户端快速上手教程

原创
作者头像
岳泽以
发布2026-03-26 21:21:21
发布2026-03-26 21:21:21
670
举报
文章被收录于专栏:PHPPHP

1. 安装和基础使用

安装

代码语言:bash
复制
composer require guzzlehttp/guzzle

基础 GET 请求

代码语言:php
复制
<?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();
}

2. 完整的请求方法示例

POST 请求

代码语言:php
复制
<?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'
        ]
    ]
]);

PUT、PATCH、DELETE 请求

代码语言:php
复制
<?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');

3. 高级配置和功能

客户端配置选项

代码语言:php
复制
<?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
复制
<?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'
]);

4. 响应处理

处理响应数据

代码语言:php
复制
<?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);

5. 异常处理

完整的异常处理

代码语言:php
复制
<?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();
}

6. 异步请求

异步请求示例

代码语言:php
复制
<?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
复制
<?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();

7. 中间件和处理器

自定义中间件

代码语言:php
复制
<?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]);

8. 实际应用案例

API 客户端类

代码语言:php
复制
<?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
复制
<?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();
}

9. 测试和模拟

使用 Mock 处理器进行测试

代码语言:php
复制
<?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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 安装和基础使用
    • 安装
    • 基础 GET 请求
  • 2. 完整的请求方法示例
    • POST 请求
    • PUT、PATCH、DELETE 请求
  • 3. 高级配置和功能
    • 客户端配置选项
    • 请求选项详解
  • 4. 响应处理
    • 处理响应数据
  • 5. 异常处理
    • 完整的异常处理
  • 6. 异步请求
    • 异步请求示例
    • 更复杂的异步示例
  • 7. 中间件和处理器
    • 自定义中间件
  • 8. 实际应用案例
    • API 客户端类
    • 使用示例
  • 9. 测试和模拟
    • 使用 Mock 处理器进行测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档