本文目录导读:

在 PHP 中测试文件上传有多种方法,以下是几种常见且实用的测试方案:
使用 PHP 内置测试类(推荐)
使用 PHPUnit 和 vfsStream
<?php
use PHPUnit\Framework\TestCase;
use org\bovigo\vfs\vfsStream;
class FileUploadTest extends TestCase
{
public function testFileUpload()
{
// 创建虚拟文件系统
$root = vfsStream::setup('uploads');
// 模拟上传文件
$file = [
'name' => 'test.txt',
'type' => 'text/plain',
'tmp_name' => vfsStream::newFile('test.txt')
->withContent('这是一段测试内容')
->at($root)
->url(),
'error' => UPLOAD_ERR_OK,
'size' => 57
];
// 调用上传处理函数
$result = handleFileUpload($file, vfsStream::url('uploads') . '/');
// 断言
$this->assertTrue($result['success']);
$this->assertFileExists(vfsStream::url('uploads') . '/test.txt');
}
// 测试上传错误
public function testFileUploadWithError()
{
$file = [
'name' => 'test.txt',
'type' => 'text/plain',
'tmp_name' => '',
'error' => UPLOAD_ERR_NO_FILE,
'size' => 0
];
$result = handleFileUpload($file, '/tmp/uploads/');
$this->assertFalse($result['success']);
$this->assertEquals('没有文件上传', $result['message']);
}
}
使用 curl 命令测试
创建测试脚本 upload_test.php
<?php
function handleFileUpload($file, $uploadDir) {
$uploadDir = rtrim($uploadDir, '/') . '/';
if ($file['error'] !== UPLOAD_ERR_OK) {
return ['success' => false, 'message' => '上传失败,错误码: ' . $file['error']];
}
if (!is_uploaded_file($file['tmp_name'])) {
return ['success' => false, 'message' => '不是一个有效的上传文件'];
}
// 验证文件类型和大小
if ($file['size'] > 2 * 1024 * 1024) {
return ['success' => false, 'message' => '文件太大'];
}
// 移动文件
$targetPath = $uploadDir . time() . '_' . basename($file['name']);
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
return ['success' => true, 'path' => $targetPath, 'message' => '上传成功'];
}
return ['success' => false, 'message' => '文件保存失败'];
}
// 处理上传请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
header('Content-Type: application/json');
echo json_encode(handleFileUpload($_FILES['file'], '/tmp/uploads/'));
}
使用 curl 测试
# 测试文件上传 curl -X POST -F "file=@/path/to/local/file.txt" http://localhost/upload_test.php # 测试图片上传 curl -X POST -F "image=@/path/to/image.png;type=image/png" http://localhost/upload_test.php # 测试文件上传并设置 MIME 类型 curl -X POST -F "file=@/path/to/document.pdf;type=application/pdf" http://localhost/upload_test.php # 测试多个文件 curl -X POST -F "files[]=@/path/to/file1.txt" -F "files[]=@/path/to/file2.txt" http://localhost/upload_test.php
编写独立的测试脚本
创建 test_upload.php
<?php
// 创建测试方法
function createTestFile($filename, $content) {
$tempDir = sys_get_temp_dir();
$tempFile = $tempDir . '/' . $filename;
file_put_contents($tempFile, $content);
return $tempFile;
}
function simulateFileUpload() {
// 模拟表单上传
$_FILES = [
'file' => [
'name' => 'test.txt',
'type' => 'text/plain',
'tmp_name' => createTestFile('phptmp', '这是模拟的上传文件内容'),
'error' => UPLOAD_ERR_OK,
'size' => 57
]
];
// 创建临时上传目录
$uploadDir = sys_get_temp_dir() . '/uploads';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 调用上传处理逻辑
$result = processUpload($uploadDir);
// 验证结果
echo "测试结果:" . json_encode($result) . "\n";
// 清理
unlink($_FILES['file']['tmp_name']);
return $result;
}
function processUpload($uploadDir) {
if (!isset($_FILES['file'])) {
return ['success' => false, 'message' => '没有找到文件'];
}
$file = $_FILES['file'];
if ($file['error'] !== UPLOAD_ERR_OK) {
return ['success' => false, 'message' => '上传错误'];
}
$targetFile = rtrim($uploadDir, '/') . '/' . $file['name'];
if (move_uploaded_file($file['tmp_name'], $targetFile)) {
return ['success' => true, 'path' => $targetFile];
}
return ['success' => false, 'message' => '移动失败'];
}
// 执行测试
simulateFileUpload();
使用 BrowserStack / TestingBot 云测试
<?php
require 'vendor/autoload.php';
class BrowserUploadTest extends PHPUnit_Extensions_Selenium2TestCase
{
public function setUp() {
$this->setBrowser('firefox');
$this->setBrowserUrl('http://localhost:3000/');
// 云测试平台配置
$this->setHost('hub-cloud.browserstack.com');
$this->setPort(80);
$this->setBrowserUrl('http://localhost');
}
public function testFileUpload() {
$this->open('/upload_form.php');
// 找到文件上传输入框
$fileInput = $this->byCssSelector('input[type="file"]');
// 设置文件路径
$fileInput->value(__DIR__ . '/test_files/upload_test.txt');
// 提交表单
$this->byId('submit')->click();
// 验证上传结果
$this->assertContains('上传成功', $this->body()->text());
}
}
完整的测试脚本示例
<?php
class FileUploadTester {
private $uploadDir;
private $testResults = [];
public function __construct($uploadDir) {
$this->uploadDir = $uploadDir;
}
public function testAll() {
$this->testTextFileUpload();
$this->testImageFileUpload();
$this->testLargeFile();
$this->testEmptyFile();
$this->testInvalidFileType();
return $this->testResults;
}
private function testTextFileUpload() {
$file = $this->createMockFile('test.txt', 'text/plain', 'Hello World');
$result = $this->uploadFile($file);
$this->testResults['text_upload'] = $result;
}
private function testImageFileUpload() {
// 创建模拟图片文件
$imageContent = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ');
$file = $this->createMockFile('test.png', 'image/png', $imageContent);
$result = $this->uploadFile($file);
$this->testResults['image_upload'] = $result;
}
private function createMockFile($name, $type, $content) {
$tempFile = tempnam(sys_get_temp_dir(), 'upload');
file_put_contents($tempFile, $content);
return [
'name' => $name,
'type' => $type,
'tmp_name' => $tempFile,
'error' => UPLOAD_ERR_OK,
'size' => strlen($content)
];
}
private function uploadFile($file) {
// 这里实现实际的上传逻辑
$targetFile = rtrim($this->uploadDir, '/') . '/' . time() . '_' . $file['name'];
if (move_uploaded_file($file['tmp_name'], $targetFile)) {
unlink($file['tmp_name']);
return ['success' => true, 'message' => '文件上传成功'];
}
return ['success' => false, 'message' => '文件上传失败'];
}
}
// 使用测试器
$tester = new FileUploadTester('/tmp/uploads/');
$results = $tester->testAll();
echo "测试结果:\n";
foreach ($results as $test => $result) {
echo $test . ': ' . ($result['success'] ? '✓' : '✗') . ' ' . $result['message'] . "\n";
}
Postman 测试
使用 Postman 进行测试:
- 创建新请求
- 选择 POST 方法
- 在 Body 中选择
form-data - 添加 key 为 file 的文件字段
- 选择要上传的文件
- 发送请求并查看响应
最佳实践建议
- 使用
is_uploaded_file()验证:确保文件确实是 HTTP POST 上传的 - 验证文件类型和大小:使用
$_FILES['file']['size']和 content type 验证 - 使用安全的文件名:不要直接使用用户提供的文件名
- 设置临时目录:确保 php.ini 中的
upload_tmp_dir可写 - 错误处理:始终检查
$_FILES['file']['error']的值
这些方法覆盖了单元测试、集成测试和手动测试的不同场景,可以根据具体需求选择使用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播