php实现异步图片上传
使用Ajax实现异步上传
在HTML中创建一个表单,通过Ajax发送图片数据到服务器。前端代码示例:
<input type="file" id="imageUpload">
<button onclick="uploadImage()">上传</button>
<script>
function uploadImage() {
const file = document.getElementById('imageUpload').files[0];
const formData = new FormData();
formData.append('image', file);
fetch('upload.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data));
}
</script>
PHP接收端处理:
if(isset($_FILES['image'])) {
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["image"]["name"]);
if(move_uploaded_file($_FILES["image"]["tmp_name"], $targetFile)) {
echo json_encode(['status' => 'success', 'path' => $targetFile]);
} else {
echo json_encode(['status' => 'error']);
}
}
使用cURL进行后台处理
对于需要后台处理的场景,可以使用PHP的cURL扩展:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/process_image.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'image' => new CURLFile($_FILES['image']['tmp_name'])
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
使用队列系统处理
对于大量图片处理,建议使用消息队列:
// 将上传任务加入队列
$queue = new Redis();
$queue->connect('127.0.0.1', 6379);
$queue->rpush('image_queue', json_encode([
'tmp_path' => $_FILES['image']['tmp_name'],
'target_path' => 'uploads/' . uniqid() . '.jpg'
]));
独立的worker进程处理队列:
while($task = $queue->blpop('image_queue', 0)) {
$data = json_decode($task[1], true);
move_uploaded_file($data['tmp_path'], $data['target_path']);
}
使用PHP的pcntl扩展创建子进程
在Linux环境下可以使用pcntl_fork创建子进程:
$pid = pcntl_fork();
if ($pid == -1) {
die('无法创建子进程');
} elseif ($pid) {
// 父进程立即返回
echo json_encode(['status' => 'processing']);
} else {
// 子进程处理上传
move_uploaded_file($_FILES['image']['tmp_name'], 'uploads/image.jpg');
exit;
}
使用Gearman分布式处理
安装Gearman扩展后:
$client = new GearmanClient();
$client->addServer();
$client->doBackground('upload_image', serialize($_FILES['image']));
Worker端代码:
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('upload_image', function($job) {
$file = unserialize($job->workload());
move_uploaded_file($file['tmp_name'], 'uploads/image.jpg');
});
while ($worker->work());
每种方法适用于不同场景,Ajax方式适合简单上传,队列系统适合高并发场景,子进程方式适合后台处理,Gearman适合分布式环境。







