本文目录导读:

- 使用 cURL(最常用)
- 使用 file_get_contents(简单场景)
- 完整的请求封装类
- 使用 GuzzleHttp(Composer 包)
- 批量测试工具
- 命令行测试脚本
- 使用 PHPUnit 测试
- 最佳实践建议
在 PHP 中模拟请求测试接口有多种方法,我来介绍几种最常用的方案:
使用 cURL(最常用)
GET 请求
<?php
function sendGetRequest($url, $headers = []) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false // 跳过SSL验证
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
return [
'status' => $httpCode,
'body' => $response,
'error' => $error
];
}
// 使用示例
$result = sendGetRequest('https://api.example.com/users', [
'Authorization: Bearer your_token',
'Content-Type: application/json'
]);
echo json_encode($result);
POST 请求
<?php
function sendPostRequest($url, $data, $headers = []) {
$ch = curl_init();
$defaultHeaders = [
'Content-Type: application/json'
];
$headers = array_merge($defaultHeaders, $headers);
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [
'status' => $httpCode,
'body' => $response
];
}
// 使用示例
$result = sendPostRequest('https://api.example.com/users', [
'name' => '张三',
'email' => 'zhangsan@example.com'
]);
使用 file_get_contents(简单场景)
<?php
// GET 请求
$url = 'https://api.example.com/users?page=1';
$options = [
'http' => [
'method' => 'GET',
'header' => "Authorization: Bearer token\r\n"
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
// POST 请求
$data = ['name' => '李四', 'age' => 25];
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://api.example.com/users', false, $context);
完整的请求封装类
<?php
class ApiClient {
private $baseUrl;
private $headers;
private $timeout;
public function __construct($baseUrl = '', $timeout = 30) {
$this->baseUrl = $baseUrl;
$this->timeout = $timeout;
$this->headers = [
'Content-Type: application/json',
'Accept: application/json'
];
}
// 设置请求头
public function setHeader($header) {
$this->headers[] = $header;
return $this;
}
// GET 请求
public function get($path, $params = []) {
$url = $this->baseUrl . $path;
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
return $this->execute($url, 'GET');
}
// POST 请求
public function post($path, $data = []) {
$url = $this->baseUrl . $path;
return $this->execute($url, 'POST', $data);
}
// PUT 请求
public function put($path, $data = []) {
$url = $this->baseUrl . $path;
return $this->execute($url, 'PUT', $data);
}
// DELETE 请求
public function delete($path) {
$url = $this->baseUrl . $path;
return $this->execute($url, 'DELETE');
}
// 执行请求
private function execute($url, $method, $data = []) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $this->headers,
CURLOPT_SSL_VERIFYPEER => false
]);
// POST 数据
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$error = curl_error($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return (object) [
'success' => $error ? false : true,
'status' => $statusCode,
'data' => $response ? json_decode($response, true) : null,
'error' => $error,
'raw' => $response
];
}
}
// 使用示例
$client = new ApiClient('https://api.example.com');
$client->setHeader('Authorization: Bearer your_token');
// GET 请求
$result = $client->get('/users', ['page' => 1, 'size' => 10]);
// POST 请求
$result = $client->post('/users', [
'name' => '王五',
'email' => 'wangwu@example.com'
]);
if ($result->success) {
echo "请求成功,状态码:" . $result->status;
print_r($result->data);
} else {
echo "请求失败:" . $result->error;
}
使用 GuzzleHttp(Composer 包)
安装
composer require guzzlehttp/guzzle
使用示例
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
$client = new Client([
'base_uri' => 'https://api.example.com',
'timeout' => 30,
'verify' => false
]);
try {
// GET 请求
$response = $client->get('/users', [
'query' => ['page' => 1, 'size' => 10],
'headers' => [
'Authorization' => 'Bearer token'
]
]);
$body = $response->getBody();
$data = json_decode($body, true);
echo "状态码:" . $response->getStatusCode();
print_r($data);
} catch (Exception $e) {
echo "请求错误:" . $e->getMessage();
}
// POST 请求
$response = $client->post('/users', [
'json' => [
'name' => '赵六',
'email' => 'zhaoliu@example.com'
],
'headers' => [
'Authorization' => 'Bearer token'
]
]);
批量测试工具
<?php
class ApiTester {
private $tests = [];
private $baseUrl;
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
}
// 添加测试用例
public function addTest($name, $method, $path, $data = [], $expectedStatus = 200) {
$this->tests[] = compact('name', 'method', 'path', 'data', 'expectedStatus');
return $this;
}
// 运行所有测试
public function run() {
$results = [];
foreach ($this->tests as $test) {
$start = microtime(true);
// 发送请求
$result = $this->sendRequest(
$test['method'],
$test['path'],
$test['data']
);
$executionTime = microtime(true) - $start;
$passed = $result['status'] == $test['expectedStatus'];
$results[] = [
'name' => $test['name'],
'passed' => $passed,
'status' => $result['status'],
'expected' => $test['expectedStatus'],
'time' => round($executionTime, 3) . 's',
'response' => $result['body']
];
}
return $results;
}
// 发送请求
private function sendRequest($method, $path, $data) {
$url = $this->baseUrl . $path;
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_SSL_VERIFYPEER => false
]);
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['status' => $status, 'body' => $body];
}
// 打印测试报告
public function printReport($results) {
$passed = 0;
$failed = 0;
echo "========== API 测试报告 ==========\n\n";
foreach ($results as $result) {
$status = $result['passed'] ? '✅ PASS' : '❌ FAIL';
echo "{$status} | {$result['name']}\n";
echo " 状态码: {$result['status']} (期望: {$result['expected']})\n";
echo " 耗时: {$result['time']}\n";
if (!$result['passed']) {
echo " 响应: {$result['response']}\n";
$failed++;
} else {
$passed++;
}
echo "\n";
}
echo "========== 测试统计 ==========\n";
echo "总测试数: " . count($results) . "\n";
echo "通过: {$passed}\n";
echo "失败: {$failed}\n";
echo "成功率: " . round($passed / count($results) * 100, 2) . "%\n";
}
}
// 使用示例
$tester = new ApiTester('http://localhost:8000/api');
// 添加测试用例
$tester->addTest('获取用户列表', 'GET', '/users')
->addTest('创建用户', 'POST', '/users', ['name' => '测试用户'], 201)
->addTest('获取单个用户', 'GET', '/users/1')
->addTest('更新用户', 'PUT', '/users/1', ['name' => '更新名称'])
->addTest('删除用户', 'DELETE', '/users/1', [], 204);
// 运行测试
$results = $tester->run();
$tester->printReport($results);
命令行测试脚本
#!/usr/bin/env php
<?php
// test_api.php
parse_str(implode('&', array_slice($argv, 1)), $args);
$method = $args['method'] ?? 'GET';
$url = $args['url'] ?? '';
$data = json_decode($args['data'] ?? '{}', true);
$token = $args['token'] ?? '';
$ch = curl_init();
$headers = ['Content-Type: application/json'];
if ($token) {
$headers[] = "Authorization: Bearer $token";
}
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_SSL_VERIFYPEER => false
]);
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
echo "状态码: $status\n";
echo "响应: $response\n";
if ($error) {
echo "错误: $error\n";
}
// 命令行使用方式
// php test_api.php method=POST url=http://localhost:8000/api/users data='{"name":"test"}' token=xxx
使用 PHPUnit 测试
<?php
use PHPUnit\Framework\TestCase;
class ApiTest extends TestCase {
private $baseUrl = 'http://localhost:8000/api';
private $client;
protected function setUp(): void {
$this->client = new Client([
'base_uri' => $this->baseUrl,
'timeout' => 10,
'http_errors' => false
]);
}
public function testGetUsers() {
$response = $this->client->get('/users');
$this->assertEquals(200, $response->getStatusCode());
$data = json_decode($response->getBody(), true);
$this->assertArrayHasKey('users', $data);
}
public function testCreateUser() {
$response = $this->client->post('/users', [
'json' => [
'name' => '测试用户',
'email' => 'test@example.com'
]
]);
$this->assertEquals(201, $response->getStatusCode());
$data = json_decode($response->getBody(), true);
$this->assertArrayHasKey('id', $data);
}
}
最佳实践建议
- 统一封装:建议使用一个统一的请求封装类,方便维护
- 错误处理:始终检查 HTTP 状态码和错误信息
- 超时设置:设置合理的超时时间,避免请求挂起
- 日志记录:记录请求和响应的日志,便于调试
- 测试数据:预先准备测试数据,确保测试可重复
- 安全管理:不要在代码中硬编码敏感信息(API密钥等)
选择哪种方法取决于你的项目复杂度:
- 简单测试 ➜
file_get_contents或简单 cURL - 中等项目 ➜ 自定义封装类
- 大型项目 ➜ GuzzleHttp 等成熟库
- 自动化测试 ➜ PHPUnit + GuzzleHttp