在PHP项目中实现文件上传后的在线预览功能,需要结合文件上传处理和不同文件类型的对应预览逻辑,下面分步骤介绍完整的实现方案。

一、基础环境配置
首先需要确保PHP环境支持文件上传,修改php.ini中的相关配置:
- file_uploads = On 开启文件上传功能
- upload_max_filesize = 20M 设置单个上传文件最大大小
- post_max_size = 20M 设置POST请求最大大小,需大于等于upload_max_filesize
- upload_tmp_dir 设置临时文件存储目录,确保目录有读写权限
二、文件上传基础实现
先完成基础的文件上传功能,将用户上传的文件保存到指定目录,同时记录文件信息到数据库或者返回文件路径。
<?php
// 处理文件上传的PHP代码
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload_file'])) {
$uploadDir = 'uploads/';
// 创建上传目录(如果不存在)
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
$file = $_FILES['upload_file'];
$fileName = basename($file['name']);
$fileTmp = $file['tmp_name'];
$fileSize = $file['size'];
$fileType = $file['type'];
$targetPath = $uploadDir . $fileName;
// 检查文件是否上传成功
if (move_uploaded_file($fileTmp, $targetPath)) {
echo json_encode([
'code' => 0,
'msg' => '上传成功',
'file_path' => $targetPath,
'file_type' => $fileType,
'file_name' => $fileName
]);
} else {
echo json_encode(['code' => 1, 'msg' => '上传失败']);
}
exit;
}
?>
<!-- 上传表单 -->
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file" required>
<button type="submit">上传文件</button>
</form>
三、不同文件类型的在线预览实现
1. 图片文件预览
图片文件可以直接通过<img>标签加载文件路径实现预览,支持jpg、png、gif等常见格式。
<?php
// 假设已经获取到上传后的图片路径 $imgPath
$imgPath = 'uploads/test.jpg';
// 判断是否为图片类型
$imgExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp'];
$ext = strtolower(pathinfo($imgPath, PATHINFO_EXTENSION));
if (in_array($ext, $imgExt)) {
echo '<img src="' . $imgPath . '" alt="图片预览" style="max-width:800px;max-height:600px;">';
} else {
echo '该文件不是图片,无法预览';
}
?>
2. PDF文件预览
PDF文件可以使用Mozilla的PDF.js库实现在线预览,需要先引入PDF.js的相关资源,然后通过JS加载PDF文件路径渲染。
<!-- 引入PDF.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<div id="pdf_container" style="width:800px;height:600px;border:1px solid #ccc;"></div>
<script>
// 假设PDF文件路径为 pdfPath
const pdfPath = 'uploads/test.pdf';
const container = document.getElementById('pdf_container');
pdfjsLib.getDocument(pdfPath).promise.then(function(pdf) {
// 获取第一页渲染
pdf.getPage(1).then(function(page) {
const scale = 1.5;
const viewport = page.getViewport({scale: scale});
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
container.appendChild(canvas);
const renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});
</script>
3. 文本文件预览
文本文件(如txt、log、php、html等)可以通过PHP读取文件内容,然后直接输出到页面中展示。
<?php
$txtPath = 'uploads/test.txt';
$txtExt = ['txt', 'log', 'php', 'html', 'css', 'js'];
$ext = strtolower(pathinfo($txtPath, PATHINFO_EXTENSION));
if (in_array($ext, $txtExt) && file_exists($txtPath)) {
$content = file_get_contents($txtPath);
// 转义HTML特殊字符,避免内容被解析为HTML标签
$content = htmlspecialchars($content);
echo '<pre style="width:800px;height:600px;overflow:auto;border:1px solid #ccc;padding:10px;">' . $content . '</pre>';
} else {
echo '该文件不是文本类型,无法预览';
}
?>
四、注意事项
- 上传文件时需要校验文件类型,避免恶意文件上传,不要仅依赖前端校验,必须做后端校验
- 文件存储目录不要放在网站根目录下,避免直接通过URL访问到敏感文件,建议放在非web可访问的目录,通过PHP读取后输出
- 大文件预览时需要做分页或者分片加载处理,避免一次性加载导致页面卡顿
- 预览PDF时需要确保PDF.js的资源地址可访问,也可以使用本地部署的PDF.js资源
- 文本文件预览时需要转义HTML特殊字符,避免文件内容中的HTML代码被浏览器执行,造成安全风险
五、完整预览逻辑封装示例
可以将不同文件类型的预览逻辑封装成一个函数,根据上传后的文件类型自动选择对应的预览方式。
<?php
function previewFile($filePath) {
if (!file_exists($filePath)) {
return '文件不存在';
}
$ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
// 图片类型
$imgExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
if (in_array($ext, $imgExt)) {
return '<img src="' . $filePath . '" alt="文件预览" style="max-width:800px;max-height:600px;">';
}
// PDF类型
if ($ext === 'pdf') {
return '<div id="pdf_container" style="width:800px;height:600px;border:1px solid #ccc;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<script>
const pdfPath = "' . $filePath . '";
const container = document.getElementById("pdf_container");
pdfjsLib.getDocument(pdfPath).promise.then(function(pdf) {
pdf.getPage(1).then(function(page) {
const scale = 1.5;
const viewport = page.getViewport({scale: scale});
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.height = viewport.height;
canvas.width = viewport.width;
container.appendChild(canvas);
page.render({canvasContext: context, viewport: viewport});
});
});
</script>';
}
// 文本类型
$txtExt = ['txt', 'log', 'php', 'html', 'css', 'js', 'json', 'xml'];
if (in_array($ext, $txtExt)) {
$content = htmlspecialchars(file_get_contents($filePath));
return '<pre style="width:800px;height:600px;overflow:auto;border:1px solid #ccc;padding:10px;">' . $content . '</pre>';
}
return '该文件类型暂不支持在线预览';
}
// 调用示例
$filePath = 'uploads/test.jpg';
echo previewFile($filePath);
?>
PHP文件上传在线预览file_preview修改时间:2026-07-07 15:54:17