使用PHP搭建网盘系统是一个涉及前端交互、后端逻辑和文件管理的综合性项目,以下是详细的实现步骤和关键代码示例,帮助理解从零开始构建基础网盘的过程。

需要规划网盘的核心功能,包括用户登录、文件上传、文件列表、文件下载和删除等,建议使用MAMP或XAMPP等本地开发环境,确保PHP版本在7.4以上,并启用fileinfo
扩展以支持文件类型检测,数据库采用MySQL,用于存储用户信息和文件元数据,如文件名、大小、上传时间、存储路径等。
数据库设计是基础,需创建两个表:users
和files
。users
表包含id
、username
、password
(建议使用password_hash
加密存储)等字段;files
表则关联用户ID,记录file_id
、original_name
、stored_name
、file_size
、upload_time
等,通过以下SQL语句创建表:
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL ); CREATE TABLE files ( file_id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, original_name VARCHAR(255) NOT NULL, stored_name VARCHAR(255) NOT NULL, file_size BIGINT NOT NULL, upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) );
用户认证部分,登录页面需验证用户输入的凭据,使用password_verify
函数对比密码哈希值,确保安全性。
session_start(); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $username = $_POST['username']; $password = $_POST['password']; $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); $stmt->execute([$username]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { $_SESSION['user_id'] = $user['id']; header('Location: dashboard.php'); } else { echo "用户名或密码错误"; } }
文件上传功能是网盘的核心,在dashboard.php
中,通过HTML表单接收文件,后端需验证文件类型和大小(如限制为10MB),并生成唯一文件名避免冲突,上传成功后,将文件信息存入数据库,关键代码如下:

if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) { $file = $_FILES['file']; $allowedTypes = ['image/jpeg', 'application/pdf', 'text/plain']; if (!in_array($file['type'], $allowedTypes)) { die("不支持的文件类型"); } if ($file['size'] > 10 * 1024 * 1024) { die("文件大小超过10MB限制"); } $storedName = uniqid() . '_' . $file['name']; move_uploaded_file($file['tmp_name'], 'uploads/' . $storedName); $stmt = $pdo->prepare("INSERT INTO files (user_id, original_name, stored_name, file_size) VALUES (?, ?, ?, ?)"); $stmt->execute([$_SESSION['user_id'], $file['name'], $storedName, $file['size']]); header('Location: dashboard.php'); }
文件列表展示通过查询数据库实现,使用表格呈现文件信息,并提供下载和删除按钮。
$stmt = $pdo->prepare("SELECT * FROM files WHERE user_id = ?"); $stmt->execute([$_SESSION['user_id']]); $files = $stmt->fetchAll(); echo "<table><tr><th>文件名</th><th>大小</th><th>上传时间</th><th>操作</th></tr>"; foreach ($files as $file) { echo "<tr> <td>{$file['original_name']}</td> <td>" . round($file['file_size'] / 1024, 2) . " KB</td> <td>{$file['upload_time']}</td> <td><a href='download.php?id={$file['file_id']}'>下载</a> | <a href='delete.php?id={$file['file_id']}'>删除</a></td> </tr>"; } echo "</table>";
文件下载通过download.php
处理,根据文件ID从数据库获取存储路径,使用header
函数设置Content-Type和Content-Disposition,强制下载文件:
$id = $_GET['id']; $stmt = $pdo->prepare("SELECT stored_name, original_name FROM files WHERE file_id = ? AND user_id = ?"); $stmt->execute([$id, $_SESSION['user_id']]); $file = $stmt->fetch(); if ($file) { $filePath = 'uploads/' . $file['stored_name']; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $file['original_name'] . '"'); readfile($filePath); }
文件删除功能需同时删除服务器上的文件和数据库记录:
$id = $_GET['id']; $stmt = $pdo->prepare("SELECT stored_name FROM files WHERE file_id = ? AND user_id = ?"); $stmt->execute([$id, $_SESSION['user_id']]); $file = $stmt->fetch(); if ($file) { unlink('uploads/' . $file['stored_name']); $stmt = $pdo->prepare("DELETE FROM files WHERE file_id = ?"); $stmt->execute([$id]); } header('Location: dashboard.php');
安全注意事项:所有用户输入需过滤(如使用htmlspecialchars
),防止SQL注入(使用预处理语句),并设置uploads
目录权限为755,避免直接执行上传文件,定期备份数据库和文件,防止数据丢失。

相关问答FAQs:
-
如何限制上传文件的类型?
在文件上传代码中,使用$allowedTypes
数组定义允许的MIME类型(如['image/jpeg', 'application/pdf']
),通过$_FILES['file']['type']
检查文件类型是否在数组内,若不在则拒绝上传,可结合finfo_file()
函数更准确检测文件类型,避免伪造MIME类型绕过限制。 -
如何实现文件分片上传以支持大文件?
可使用JavaScript的FileReader
API将大文件分割为多个小块(如每片1MB),通过AJAX异步上传各分片,并在PHP端临时存储,上传完成后,使用file_put_contents
的FILE_APPEND
模式合并所有分片,需额外设计数据库表记录分片状态,并处理断点续传逻辑,确保上传可靠性。