php实现上传视频文件
上传视频文件的基本实现
在PHP中实现视频文件上传需要处理文件接收、验证、移动和存储等步骤。以下是一个完整的实现示例:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["video"]["name"]);
$uploadOk = 1;
$videoFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
// 检查是否为真实视频文件
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["video"]["tmp_name"]);
if($check !== false) {
$uploadOk = 1;
} else {
echo "文件不是视频。";
$uploadOk = 0;
}
}
// 检查文件是否已存在
if (file_exists($targetFile)) {
echo "抱歉,文件已存在。";
$uploadOk = 0;
}
// 限制文件大小(50MB)
if ($_FILES["video"]["size"] > 50000000) {
echo "抱歉,您的文件太大。";
$uploadOk = 0;
}
// 允许特定格式
$allowedFormats = ["mp4", "avi", "mov", "wmv"];
if(!in_array($videoFileType, $allowedFormats)) {
echo "抱歉,只允许 MP4, AVI, MOV, WMV 文件。";
$uploadOk = 0;
}
// 检查上传状态
if ($uploadOk == 0) {
echo "抱歉,您的文件未被上传。";
} else {
if (move_uploaded_file($_FILES["video"]["tmp_name"], $targetFile)) {
echo "文件 ". htmlspecialchars(basename($_FILES["video"]["name"])). " 已上传。";
} else {
echo "抱歉,上传文件时出现错误。";
}
}
}
?>
前端HTML表单
需要创建一个HTML表单来提交视频文件:
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="video">选择视频文件:</label>
<input type="file" name="video" id="video" accept="video/*">
<input type="submit" value="上传视频" name="submit">
</form>
安全增强措施
增加文件重命名功能,防止文件名冲突和安全问题:
// 生成唯一文件名
$newFileName = uniqid().'.'.$videoFileType;
$targetFile = $targetDir . $newFileName;
添加MIME类型验证:
$allowedMimeTypes = ["video/mp4", "video/avi", "video/quicktime", "video/x-ms-wmv"];
$fileMimeType = mime_content_type($_FILES["video"]["tmp_name"]);
if(!in_array($fileMimeType, $allowedMimeTypes)) {
echo "无效的视频文件类型。";
$uploadOk = 0;
}
大文件上传处理
对于大视频文件,可能需要调整PHP配置:

// 在脚本开始处设置
ini_set('upload_max_filesize', '100M');
ini_set('post_max_size', '100M');
ini_set('max_execution_time', '300');
或在php.ini中修改:
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300
进度显示实现
使用AJAX实现上传进度显示:
// JavaScript部分
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function(e) {
var percent = Math.round((e.loaded / e.total) * 100);
document.getElementById("progress").innerHTML = percent + "%";
}, false);
分块上传处理
对于超大视频文件,考虑分块上传:

// 前端分块处理
function uploadChunk(file, chunkSize) {
var chunks = Math.ceil(file.size / chunkSize);
for(var i=0; i<chunks; i++) {
var chunk = file.slice(i*chunkSize, (i+1)*chunkSize);
// 发送每个分块到服务器
}
}
// PHP接收分块
file_put_contents($targetFile, file_get_contents($_FILES["chunk"]["tmp_name"]), FILE_APPEND);
视频预览生成
上传后生成缩略图预览:
// 使用FFmpeg生成缩略图
$thumbPath = $targetDir . pathinfo($newFileName, PATHINFO_FILENAME) . '.jpg';
exec("ffmpeg -i ".$targetFile." -ss 00:00:01 -vframes 1 ".$thumbPath);
数据库记录存储
将上传信息存入数据库:
// 连接数据库后执行
$stmt = $pdo->prepare("INSERT INTO videos (filename, path, size, upload_date) VALUES (?, ?, ?, NOW())");
$stmt->execute([$newFileName, $targetFile, $_FILES["video"]["size"]]);
错误处理与日志
添加详细的错误处理和日志记录:
try {
// 上传处理代码
} catch (Exception $e) {
error_log("上传错误: " . $e->getMessage());
header("HTTP/1.1 500 Internal Server Error");
echo "上传过程中发生错误";
}
以上实现涵盖了视频上传的基本功能和常见需求扩展,可以根据实际项目需求进行调整和扩展。






