php实现相册功能
数据库设计
创建相册系统需要设计数据库表来存储用户、相册和照片信息。常见的表结构包括:
- users表:存储用户信息(id, username, password, email等)
- albums表:存储相册信息(id, user_id, title, description, created_at)
- photos表:存储照片信息(id, album_id, filename, caption, uploaded_at)
SQL示例:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) NOT NULL
);
CREATE TABLE albums (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(100) NOT NULL,
description TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE photos (
id INT AUTO_INCREMENT PRIMARY KEY,
album_id INT NOT NULL,
filename VARCHAR(255) NOT NULL,
caption TEXT,
uploaded_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (album_id) REFERENCES albums(id)
);
文件上传处理
实现照片上传功能需要处理文件上传表单并验证文件类型和大小。

// 检查上传目录是否存在
$uploadDir = 'uploads/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// 处理上传
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['photo'])) {
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
$maxSize = 2 * 1024 * 1024; // 2MB
$file = $_FILES['photo'];
if (in_array($file['type'], $allowedTypes) && $file['size'] <= $maxSize) {
$filename = uniqid() . '_' . basename($file['name']);
$targetPath = $uploadDir . $filename;
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
// 保存到数据库
$stmt = $pdo->prepare("INSERT INTO photos (album_id, filename) VALUES (?, ?)");
$stmt->execute([$_POST['album_id'], $filename]);
}
}
}
相册展示
创建相册浏览页面需要从数据库查询数据并展示。
// 获取用户相册列表
$userId = $_SESSION['user_id'];
$stmt = $pdo->prepare("SELECT * FROM albums WHERE user_id = ?");
$stmt->execute([$userId]);
$albums = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 显示相册
foreach ($albums as $album) {
echo '<div class="album">';
echo '<h3>' . htmlspecialchars($album['title']) . '</h3>';
echo '<p>' . htmlspecialchars($album['description']) . '</p>';
// 获取相册照片
$stmt = $pdo->prepare("SELECT * FROM photos WHERE album_id = ? LIMIT 1");
$stmt->execute([$album['id']]);
$coverPhoto = $stmt->fetch(PDO::FETCH_ASSOC);
if ($coverPhoto) {
echo '<img src="uploads/' . htmlspecialchars($coverPhoto['filename']) . '" alt="Cover">';
}
echo '</div>';
}
用户认证
实现基本的用户注册和登录功能保障系统安全。

// 用户注册
if (isset($_POST['register'])) {
$username = $_POST['username'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$email = $_POST['email'];
$stmt = $pdo->prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
$stmt->execute([$username, $password, $email]);
}
// 用户登录
if (isset($_POST['login'])) {
$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'];
$_SESSION['username'] = $user['username'];
}
}
安全措施
确保系统安全需要实施以下防护措施:
- 使用预处理语句防止SQL注入
- 对用户上传文件进行严格验证
- 对输出内容使用htmlspecialchars()转义
- 使用password_hash()存储密码
- 设置文件上传目录不可执行
// 文件类型验证加强版
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
if (!in_array($mime, $allowedTypes)) {
die('Invalid file type');
}
性能优化
提升相册系统性能可以考虑:
- 为常用查询字段添加索引
- 实现图片缩略图生成
- 使用分页加载大量照片
- 缓存常用数据
缩略图生成示例:
function createThumbnail($sourcePath, $destPath, $maxWidth = 200, $maxHeight = 200) {
list($origWidth, $origHeight, $type) = getimagesize($sourcePath);
$ratio = $origWidth / $origHeight;
$newWidth = $maxWidth;
$newHeight = $maxHeight;
if ($maxWidth/$maxHeight > $ratio) {
$newWidth = $maxHeight * $ratio;
} else {
$newHeight = $maxWidth / $ratio;
}
$image = null;
switch ($type) {
case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($sourcePath); break;
case IMAGETYPE_PNG: $image = imagecreatefrompng($sourcePath); break;
case IMAGETYPE_GIF: $image = imagecreatefromgif($sourcePath); break;
}
$thumb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
switch ($type) {
case IMAGETYPE_JPEG: imagejpeg($thumb, $destPath); break;
case IMAGETYPE_PNG: imagepng($thumb, $destPath); break;
case IMAGETYPE_GIF: imagegif($thumb, $destPath); break;
}
}






