介绍
在现代PHP Web开发中,几乎没有项目能够避免发送HTTP请求。无论是与外部API集成、从远程服务器获取数据、提交表单,还是检查资源可用性——熟练使用HTTP客户端的能力是每位PHP开发者的必备技能。
本文将解析在PHP中创建HTTP客户端的三种主要方式:内置函数file_get_contents和cURL,以及流行的库Guzzle。你将学习如何正确发送GET和POST请求、处理错误、处理标头和超时。本材料对初学者和有志于系统化知识的经验丰富的开发者均适用。
1. 最简单的方式:file_get_contents
在PHP中发送GET请求最快的方法是使用带URL的file_get_contents()函数。但这种方法存在严重局限性。
简单的GET请求
<?php$url = 'https://api.example.com/users';$response = file_get_contents($url);if ($response === false) { echo '获取数据时出错';} else { echo $response;}?>通过流上下文添加标头
要添加标头或更改请求方法,需要使用stream_context_create():
<?php$url = 'https://api.example.com/data';$options = [ 'http' => [ 'method' => 'GET', 'header' => "Accept: application/json\\r" . "Authorization: Bearer your-token\\r" ]];$context = stream_context_create($options);$response = file_get_contents($url, false, $context);if ($response === false) { echo '请求错误';} else { $data = json_decode($response, true); print_r($data);}?>通过file_get_contents发送POST请求
<?php$url = 'https://api.example.com/create';$data = ['name' => 'John', 'email' => 'john@example.com'];$options = [ 'http' => [ 'method' => 'POST', 'header' => "Content-Type: application/json\\r", 'content' => json_encode($data) ]];$context = stream_context_create($options);$response = file_get_contents($url, false, $context);?>file_get_contents的缺点:
- 不支持超时(默认无限等待)
- 难以处理连接错误
- 无法分部分下载文件
- 不适合复杂场景
2. 强大工具:cURL
cURL是PHP中处理HTTP的标准工具。它提供对请求的完全控制,并支持几乎所有协议功能。
基本初始化和GET请求
<?php$ch = curl_init('https://api.example.com/users');curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$response = curl_exec($ch);if (curl_errno($ch)) { echo 'cURL错误:' . curl_error($ch);} else { $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); echo "HTTP代码:$httpCode"; echo $response;}curl_close($ch);?>带数据的POST请求
<?php$ch = curl_init('https://api.example.com/users');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ 'name' => 'Jane Doe', 'email' => 'jane@example.com' ]), CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json' ], CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 10]);$response = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);