php 实现视频上传
实现视频上传的基本流程
使用PHP实现视频上传功能需要处理文件接收、验证、存储等步骤。以下是一个完整的实现方案:
创建HTML表单
创建一个包含文件上传字段的HTML表单,确保设置enctype="multipart/form-data"属性:
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="video" accept="video/*">
<input type="submit" value="上传视频">
</form>
处理上传的PHP脚本
在upload.php中编写处理上传的逻辑:
<?php
$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;
}
// 允许特定视频格式
if($videoFileType != "mp4" && $videoFileType != "avi" && $videoFileType != "mov"
&& $videoFileType != "wmv" ) {
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 "抱歉,上传文件时出错。";
}
}
?>
安全增强措施
为确保上传过程的安全性,可以添加以下额外检查:
// 检查文件是否通过HTTP POST上传
if (!is_uploaded_file($_FILES["video"]["tmp_name"])) {
die("可能的文件上传攻击");
}
// 设置自定义文件名防止覆盖
$newFileName = uniqid().'.'.$videoFileType;
$targetFile = $targetDir . $newFileName;
服务器配置调整
在php.ini中调整以下参数以适应视频上传:
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300
memory_limit = 128M
处理大文件上传
对于特别大的视频文件,可以考虑分块上传:
// 前端JavaScript分块上传逻辑
// 使用XMLHttpRequest或Fetch API将文件分成多个块上传
// PHP端接收分块并合并
$chunkNumber = $_POST['chunkNumber'];
$totalChunks = $_POST['totalChunks'];
$fileName = $_POST['fileName'];
// 存储临时分块
file_put_contents("uploads/$fileName.part$chunkNumber", file_get_contents($_FILES['file']['tmp_name']));
// 所有分块上传完成后合并
if ($chunkNumber == $totalChunks) {
$finalFile = fopen("uploads/$fileName", 'wb');
for ($i = 1; $i <= $totalChunks; $i++) {
$chunk = file_get_contents("uploads/$fileName.part$i");
fwrite($finalFile, $chunk);
unlink("uploads/$fileName.part$i");
}
fclose($finalFile);
}
视频转码处理
上传后可能需要转码为统一格式:
// 使用FFmpeg进行转码
exec("ffmpeg -i uploads/original.mp4 -c:v libx264 -crf 23 -preset fast -c:a aac -b:a 128k uploads/converted.mp4");
数据库记录
将上传信息存入数据库:
$pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'username', 'password');
$stmt = $pdo->prepare("INSERT INTO videos (filename, size, type, upload_date) VALUES (?, ?, ?, NOW())");
$stmt->execute([$newFileName, $_FILES["video"]["size"], $videoFileType]);
权限设置
确保上传目录有正确权限:
chmod 755 uploads/
chown www-data:www-data uploads/
错误处理
完善错误处理机制:
switch ($_FILES['video']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
die('文件太大');
case UPLOAD_ERR_PARTIAL:
die('文件部分上传');
case UPLOAD_ERR_NO_FILE:
die('未选择文件');
case UPLOAD_ERR_NO_TMP_DIR:
die('服务器配置错误');
case UPLOAD_ERR_CANT_WRITE:
die('写入磁盘失败');
default:
die('未知错误');
}






