logo
0
0
WeChat Login

悦·图床 YueAlbum

轻量优雅的自托管图床应用,PHP 8.0+ / MySQL 5.7+,零框架依赖,原生开发。 Author : yefengs.com


目录


简介

悦·图床(YueAlbum)是一款面向个人和小团队的自托管图床应用。它以"轻量、优雅、实用"为设计理念,采用原生 PHP + 原生 JavaScript 开发,不依赖任何框架,部署简单、资源占用低。

主要特点:

  • 零框架依赖 — 原生 PHP 8.0+ 开发,无 Composer、无 Laravel、无 ThinkPHP
  • 轻量高效 — 核心代码不到 3MB,运行速度快,服务器资源占用极低
  • 功能完备 — 上传、管理、编辑、水印、EXIF、分类、回收站一应俱全
  • 安全可靠 — RBAC 权限模型、CSRF 防护、SQL 参数化查询、文件类型校验
  • 响应式设计 — 完美适配桌面端与移动端,配色温柔舒适

功能特性

上传与管理

  • 🖼 多方式上传 — 拖拽上传、粘贴上传、点击选择,支持批量操作
  • 🔗 一键外链 — 上传即得直链、HTML、Markdown、BBCode 四种格式
  • 📁 分类整理 — 创建分类、设置封面、按分类筛选
  • 收藏功能 — 快速收藏重要图片,独立筛选查看
  • 🗑 回收站 — 安全删除,支持恢复和彻底清除

图片编辑

  • ✂️ 裁切 — 自由裁切图片区域
  • 🔄 缩放 — 等比缩放至指定尺寸
  • 🔃 旋转 — 90°/180°/270° 旋转,支持透明背景
  • 🏷 EXIF 编辑 — 查看原始 EXIF,编辑拍摄参数
  • 💧 即时水印 — 编辑器中直接添加水印

水印系统

  • 📍 九宫格定位 — 9 个位置精准放置(左上/居中/右下等)
  • 📐 灵活尺寸 — 固定像素或百分比宽度,自动等比缩放
  • 🌫 透明度控制 — 0-100 透明度,PNG Alpha 通道完美保留
  • 📏 百分比边距 — 基于图片尺寸的百分比边距,适配各种分辨率
  • 🎯 多模板 — 创建多个水印模板,上传时选择应用

EXIF 模板

  • 📷 预设参数 — 创建常用拍摄参数模板(相机、镜头、光圈、快门等)
  • 🔧 自动填充 — 编辑器中选择模板自动填入
  • 📍 GPS 支持 — 纬度/经度/海拔信息记录

匿名上传

  • 🌐 独立开关 — 可选开启/关闭匿名上传功能
  • ⚙️ 独立配置 — 匿名用户独立的文件大小限制、格式、水印设置
  • 🔒 IP 限流 — 按IP限制每日上传次数
  • 💧 强制水印 — 可设为匿名上传必须添加水印

存储与命名

  • 📂 目录结构 — 年/月/日、年/月、年、扁平四种目录组织方式
  • 📝 文件名规则 — 随机字符串、日期+随机、保留原名、哈希前12位
  • 🌍 图片域名 — 支持配置独立图片域名,CDN 加速更方便

权限与安全

  • 🛡 RBAC 权限 — admin/user 角色体系,支持细粒度权限覆盖
  • 🔐 CSRF 防护 — 所有写操作验证 CSRF Token
  • 🗃 参数化查询 — PDO 预处理语句,杜绝 SQL 注入
  • 📋 文件校验 — 上传文件 MIME 类型检测,防止恶意文件

技术架构

技术栈

组件技术选型说明
后端语言PHP 8.0+推荐 PHP 8.4
数据库MySQL 5.7+MariaDB 10.3+ 兼容
图片处理GD 库支持 JPEG/PNG/GIF/WebP
前端原生 JavaScript无框架依赖
样式原生 CSSCSS 变量 + 响应式
图标内联 SVG Sprite零外部依赖

核心架构

请求流程:

  浏览器请求
      ↓
  index.php (入口,定义常量)
      ↓
  core/bootstrap.php (引导:自动加载、数据库、会话、认证)
      ↓
  config/routes.php (路由配置)
      ↓
  core/Router.php (路由分发)
      ├── 前台 → layout.php + pages/*.php
      ├── 后台 → admin/layout.php + admin/pages/*.php
      └── API  → api/*.php

核心类说明:

文件职责
Databasecore/Database.phpPDO 封装,CRUD、软删除、事务
Authcore/Auth.php登录/登出、RBAC 权限校验
Sessioncore/Session.php会话管理、CSRF 令牌
Settingscore/Settings.php系统设置读写(数据库 kv 表)
Routercore/Router.phpURL 解析与请求分发
ImageProcessorcore/ImageProcessor.php图片处理核心:格式转换、水印、裁切、缩放、旋转、EXIF、缩略图

辅助函数(core/helpers.php):

函数说明
site_url($path)获取站点 URL(优先使用数据库配置)
upload_url($path)获取图片 URL(优先使用图片域名配置)
asset_url($path)获取静态资源 URL
e($str)HTML 转义
format_size($bytes)格式化文件大小
json_response($data)JSON 响应输出
time_ago($datetime)相对时间显示

目录结构

yue-album/
├── index.php              应用入口
├── install.php            安装向导入口
├── layout.php             前台布局模板
├── nginx.conf.example     Nginx 配置参考
│
├── admin/                 后台管理
│   ├── layout.php         后台布局模板
│   ├── login.php          登录页
│   └── pages/             后台功能页面
│       ├── dashboard.php  仪表盘
│       ├── images.php     图片管理
│       ├── editor.php     图片编辑器
│       ├── categories.php 分类管理
│       ├── trash.php      回收站
│       ├── watermarks.php 水印模板
│       ├── exif-templates.php  EXIF模板
│       ├── upload-config.php   上传配置
│       ├── settings.php   系统设置
│       ├── anonymous.php  匿名配置
│       ├── users.php      用户管理
│       └── profile.php    个人信息
│
├── api/                   API 接口
│   ├── auth.php           认证接口(登录/登出/改密)
│   ├── upload.php         上传接口
│   ├── images.php         图片查询接口
│   ├── images_edit.php    图片编辑接口
│   ├── categories.php     分类接口
│   ├── watermarks.php     水印接口
│   ├── exif.php           EXIF模板接口
│   ├── settings.php       设置接口
│   └── users.php          用户接口
│
├── assets/                静态资源
│   ├── css/
│   │   ├── system.css     公共样式(前后台共用)
│   │   ├── front.css      前台样式
│   │   ├── admin.css      后台样式
│   │   └── icons.css      图标样式
│   ├── js/
│   │   ├── app.js         前台脚本
│   │   └── admin.js       后台公共脚本
│   ├── img/               静态图片(favicon 等)
│   └── icons.php          SVG Sprite 图标定义
│
├── config/                配置文件
│   ├── database.php       数据库配置(安装后自动生成)
│   ├── routes.php         路由配置
│   └── system.php         系统配置
│
├── core/                  核心类库
│   ├── bootstrap.php      应用引导
│   ├── Database.php       数据库封装
│   ├── Auth.php           认证与权限
│   ├── Session.php        会话管理
│   ├── Settings.php       设置管理
│   ├── Router.php         路由分发
│   ├── ImageProcessor.php 图片处理核心
│   └── helpers.php        辅助函数
│
├── install/               安装向导
│   ├── index.php          安装流程
│   ├── schema.sql         数据库结构
│   └── view.php           安装界面
│
├── pages/                 前台页面
│   ├── home.php           首页
│   ├── upload.php         上传页
│   ├── gallery.php        图库页
│   ├── image.php          图片详情
│   └── 404.php            404 页
│
└── uploads/               图片存储目录
    └── (按日期/自定义规则组织)

数据库设计

共 7 张数据表,统一使用 ya_ 前缀:

表名说明关键字段
ya_users用户表username, password, nickname, role, permissions(JSON), status
ya_images图片表user_id, category_id, title, file_path, file_size, width, height, format, hash, exif_data(JSON), is_favorite, status
ya_categories分类表name, slug, description, cover_image, image_count
ya_watermarks水印模板表name, image_path, position, margin_x(%), margin_y(%), size_type, size_width, size_percent, opacity
ya_exif_templatesEXIF模板表name, camera, make, lens, exposure, aperture, iso, focal_length, author, latitude, longitude, altitude
ya_settings系统设置表key, value(kv 结构)
ya_access_logs外链访问日志image_id, referer, ip, user_agent

关键设计说明:

  • 软删除:图片删除时 status 标记为 trash,文件移入 uploads/.trash/ 目录,支持恢复
  • 哈希去重hash 字段存储文件 SHA-256,上传时检测重复
  • 权限覆盖ya_users.permissions 字段存储 JSON 数组,可覆盖角色默认权限(如 ["category.manage"] 授权,["!image.manage-all"] 禁止)
  • 边距百分比:水印边距 margin_x/margin_y 使用 decimal(5,2) 百分比,适配不同分辨率图片

路由机制

YueAlbum 采用简洁的自研路由,同时兼容 Apache mod_rewrite 和 Nginx try_files

前台路由:
  /              → 首页
  /upload        → 上传页
  /gallery       → 图库页
  /image/{id}    → 图片详情

后台路由:
  /admin                → 仪表盘
  /admin/images         → 图片管理
  /admin/images?action=edit&id={id}  → 图片编辑器
  /admin/categories     → 分类管理
  /admin/trash          → 回收站
  /admin/watermarks     → 水印模板
  /admin/exif-templates → EXIF模板
  /admin/upload-config  → 上传配置
  /admin/settings       → 系统设置
  /admin/anonymous      → 匿名配置
  /admin/users          → 用户管理
  /admin/profile        → 个人信息

API 路由:
  /api/auth/login       POST  登录
  /api/auth/logout      POST  登出
  /api/upload           POST  上传图片
  /api/upload/delete    POST  删除图片
  /api/upload/batch     POST  批量上传
  /api/images/list      GET   图片列表
  /api/images/detail    GET   图片详情
  /api/images_edit/*    POST  图片编辑操作
  /api/categories/*     GET/POST  分类操作
  /api/watermarks/*     GET/POST  水印操作
  /api/exif/*           GET/POST  EXIF操作
  /api/settings/update  POST  更新设置
  /api/users/*          GET/POST  用户操作

路由解析流程:

  1. Router::resolveRoute() 优先读取 $_GET['route'](Apache mod_rewrite 传入)
  2. 若为空,从 REQUEST_URI 中解析并去除基础路径(兼容 Nginx try_files)
  3. api/ 开头的请求进入 API 处理,自动映射到 api/*.php
  4. admin 开头的请求进入后台处理,登录页单独处理,其他需认证
  5. 其余请求进入前台处理,映射到 pages/*.php

图片处理流程

上传图片
    ↓
ImageProcessor::process($sourcePath, $options)
    ↓
┌── getimagesize() → 获取图片信息
├── createFromSource() → 创建 GD 图像资源
├── ensureMemory() → 动态提升 memory_limit(防止大图 OOM)
├── imagepalettetotruecolor() → 确保真彩色
├── addWatermark() → 添加水印(如已配置)
│   ├── 超大水印图预缩放至临时文件
│   ├── 百分比/固定尺寸 → 计算目标尺寸
│   ├── calcPosition() → 九宫格位置计算
│   ├── 逐像素 Alpha 调整 → 实现 PNG 半透明
│   └── imagecopy() → 合并水印(保留透明通道)
├── buildSubDir() → 根据路径规则生成子目录
├── generateFilename() → 根据命名规则生成文件名
├── saveImage() → 保存为指定格式和质量
└── 返回处理结果(路径、尺寸、大小、格式)
    ↓
写入数据库 ya_images 记录
    ↓
返回外链信息(url/html/markdown/bbcode)

部署指南

环境要求

项目最低要求推荐
PHP8.0+8.4
MySQL5.7+8.0
PHP 扩展pdo_mysql, gd, mbstring, json同左
GD 库支持 JPEG/PNG支持 WebP 更佳
磁盘空间100MB(程序 + 首批图片)视图片量而定
内存128MB(PHP memory_limit)256MB+(大图处理)

安装步骤

1. 下载程序

将程序文件上传到网站目录。支持根目录或二级目录部署:

# 根目录部署
/var/www/html/

# 二级目录部署
/var/www/html/yue-album/

2. 设置目录权限

# config/ 目录需要写入数据库配置
chmod 755 config/

# uploads/ 目录需要写入图片
chmod 755 uploads/

3. 配置 Web 服务器

参照下方 Web 服务器配置 章节。

4. 运行安装向导

浏览器访问站点地址,自动进入安装向导:

  1. 环境检测 — 检查 PHP 版本、扩展、目录权限
  2. 数据库配置 — 填写主机、端口、库名、用户名、密码、表前缀
  3. 管理员设置 — 设置管理员用户名和密码
  4. 完成安装 — 自动创建数据表和配置文件

5. 登录后台

安装完成后访问 /admin 登录管理后台。

Web 服务器配置

Nginx(推荐)

在 Nginx 的 server 块中添加:

# 根目录部署
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

# 二级目录部署(如 /yue-album)
location /yue-album/ {
    try_files $uri $uri/ /yue-album/index.php?$query_string;

    # 禁止访问 uploads 目录中的 PHP 文件
    location ~ ^/yue-album/uploads/.*\.(php|phtml|php3|php4|php5|php7|phps)$ {
        deny all;
    }

    # 禁止访问敏感文件
    location ~ ^/yue-album/.*\.(env|sql|log|md)$ {
        deny all;
    }

    # 静态资源缓存
    location ~ ^/yue-album/.*\.(jpg|jpeg|png|gif|webp|avif|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

# 重要:上传文件大小限制
client_max_body_size 20m;

⚠️ client_max_body_size 默认仅 1MB,图床应用必须设置更大值,否则上传会返回 413 错误。

Apache

项目自带 .htaccess 文件,确保服务器已开启 mod_rewrite

# 确认 httpd.conf 或虚拟主机配置中有:
AllowOverride All

生产环境优化

1. PHP 配置

创建 .user.ini 文件(放在项目根目录或 uploads 目录):

upload_max_filesize = 20M
post_max_size = 20M
memory_limit = 256M
max_execution_time = 60

2. 关闭错误显示

index.php 中已默认关闭,确认以下设置:

ini_set('display_errors', 0);
error_reporting(E_ALL);  // 错误仍会写入日志
ini_set('log_errors', 1);

3. HTTPS 配置

建议为站点配置 HTTPS,可通过 Let's Encrypt 免费获取证书。

4. 上传目录安全

确保 Nginx/Apache 配置禁止执行 uploads/ 目录中的 PHP 文件(参考上方 Nginx 配置)。


使用说明

前台功能

首页

站点首页展示介绍信息和快速上传入口。

上传

  • 支持拖拽上传:将图片拖入上传区域
  • 支持粘贴上传:在页面内 Ctrl+V 粘贴剪贴板图片
  • 支持点击选择:点击上传区域选择文件
  • 上传成功后即时显示四种外链格式,一键复制

图库

登录用户的个人图库,按时间线浏览所有已上传图片。

图片详情

查看单张图片的详细信息,包括 EXIF 数据、外链地址等。

后台管理

登录后台(/admin)后可使用以下功能模块:

仪表盘

  • 图片总数、存储用量、用户数、今日上传
  • 用户上传排行
  • 最近上传图片

图片管理

  • 网格/列表视图浏览图片
  • 按分类、收藏、日期筛选
  • 搜索图片(标题/文件名)
  • 点击缩略图弹出大图预览,获取外链
  • 批量选择操作(移动分类、删除等)
  • 跳转编辑器进行高级编辑

图片编辑器

  • 基础信息 — 修改标题、分类、标签
  • 裁切 — 自由区域裁切
  • 缩放 — 按最大边长等比缩放
  • 旋转 — 90°/180°/270° 旋转
  • 水印 — 选择水印模板,一键添加
  • EXIF — 查看/编辑拍摄参数,支持模板快速填充
  • 返回时自动恢复图片列表的分页状态

分类管理

  • 创建/编辑/删除分类
  • 设置分类封面和描述
  • 自定义排序
  • 查看每个分类的图片数量

水印模板

  • 上传水印图片(推荐 PNG 透明底)
  • 九宫格定位选择
  • 固定像素或百分比尺寸
  • 百分比边距设置
  • 0-100 透明度调节
  • 设为默认水印

EXIF 模板

  • 创建常用拍摄参数模板
  • 支持字段:相机、制造商、镜头、快门、光圈、ISO、焦距、作者、GPS
  • 编辑器中一键选择模板填充

回收站

  • 查看已删除的图片
  • 恢复误删图片
  • 彻底删除(释放空间)

上传配置

  • 默认输出格式(JPEG/WebP/PNG)
  • 输出质量(1-100)
  • 最大文件大小限制
  • 缩略图开关和尺寸

系统设置

  • 基础设置
    • 站点名称
    • 站点 URL(用于生成外链地址,配置后优先使用)
    • 图片域名及路径(配置后所有图片外链使用此域名,适合 CDN 场景)
  • 图片存储
    • 保存目录结构:年/月/日年/月扁平
    • 文件名规则:随机字符串、日期+随机、保留原名、哈希前12位
  • 匿名上传 — 开关

匿名配置

  • 文件大小限制
  • 每日上传上限(按 IP)
  • 默认格式
  • 强制水印
  • 水印模板选择
  • 默认分类

用户管理

  • 创建/编辑/禁用用户
  • 角色分配(admin/user)
  • 细粒度权限配置(覆盖角色默认权限)
  • 查看用户上传统计

个人信息

  • 修改昵称
  • 修改密码

系统配置详解

站点 URL 与图片域名

YueAlbum 支持站点 URL图片域名两层 URL 配置:

配置项作用示例
站点 URL整站访问地址,影响页面跳转和资源路径https://example.com/yue-album
图片域名图片外链专用域名,适合 CDNhttps://img.example.com/yue-album
  • 未配置「站点 URL」时,系统自动从 $_SERVER['SCRIPT_NAME'] 推导
  • 未配置「图片域名」时,图片外链使用站点 URL
  • 配置「图片域名」后,所有直链、HTML、Markdown、BBCode 中的图片地址都使用此域名

图片存储规则

保存目录结构决定图片在 uploads/ 下的组织方式:

选项路径示例适用场景
年/月/日uploads/2026/04/20/xxx.jpg默认,图片量大时推荐
年/月uploads/2026/04/xxx.jpg中等图片量
uploads/2026/xxx.jpg图片量较少
扁平uploads/xxx.jpg所有图片同一目录

文件名规则决定上传后的文件名生成方式:

规则示例说明
随机字符串143022a3f2b1c4d8.jpg默认,安全性高
日期+随机20260420_a3f2b1.jpg可读性好,按日期排序
保留原名风景照片.jpg保留原始文件名,重名自动加后缀
哈希前12位e3b0c44295f1.jpg基于文件内容,天然去重

RBAC 权限体系

系统内置以下权限项:

权限标识分组说明
settings.manage系统修改系统设置
watermark.manage配置管理水印模板
exif-template.manage配置管理EXIF模板
upload-config.manage配置修改上传配置
category.manage内容管理分类
user.manage系统管理用户
trash.empty系统清空回收站
image.manage-all内容管理所有用户的图片
  • admin 角色默认拥有全部权限
  • user 角色默认只能管理自己的图片
  • 通过「用户管理」可为特定用户覆盖权限:添加权限项授权,加 ! 前缀禁止

注意事项

安全相关

  1. 上传目录禁止执行 PHP — Nginx/Apnginx 必须配置禁止 uploads/ 目录执行 PHP 文件
  2. 修改默认密码 — 安装后请及时修改管理员密码
  3. HTTPS — 生产环境强烈建议启用 HTTPS
  4. 目录权限config/uploads/ 需要写入权限,其他目录不应给写权限
  5. 敏感文件 — Nginx/Apache 配置禁止访问 .env.sql.log 文件

性能相关

  1. 上传大小限制 — 需同时调整 PHP(upload_max_filesize/post_max_size)和 Web 服务器(Nginx client_max_body_size)的限制
  2. 内存限制 — 处理大图(尤其是旋转/水印操作)需要较多内存,建议 memory_limit ≥ 256M。系统会自动动态提升内存,但受限于 PHP 全局配置
  3. GD vs Imagick — 当前仅支持 GD 库。GD 处理超大图片(5000px+)时内存消耗较大,Imagick 性能更好但暂未集成
  4. 图片数量 — 单目录图片超过 10 万时建议使用年/月/日目录结构,避免文件系统性能下降

部署相关

  1. 二级目录部署 — 完全支持,Nginx 的 location 块需对应二级路径
  2. 反向代理 — 如使用反向代理(如宝塔面板),确保正确传递 SCRIPT_NAMEREQUEST_URI
  3. 数据库前缀 — 安装时可自定义表前缀,默认 ya_,多应用共享数据库时可避免冲突
  4. 时区 — 系统默认使用 Asia/Shanghai 时区,可在 bootstrap.php 中修改

使用相关

  1. 水印透明度 — PNG 水印的透明度通过逐像素 Alpha 通道调整实现,而非 imagecopymerge(该函数不支持 Alpha 通道,会导致透明区域变黑)
  2. 编辑器返回 — 从图片编辑器返回时会自动恢复之前的列表分页位置
  3. 匿名上传限流 — 按 IP 限制每日上传次数,通过 ya_access_logs 表记录
  4. 收藏功能 — 图片收藏为独立标记,不影响分类归属

常见问题

上传图片返回 413 错误

Nginx 的 client_max_body_size 默认仅 1MB。在 Nginx 配置中添加:

client_max_body_size 20m;

修改后重启 Nginx。

上传图片提示文件过大

需同时调整 PHP 和 Web 服务器的限制:

  1. PHP:在项目根目录创建 .user.ini
    upload_max_filesize = 20M
    post_max_size = 20M
    
  2. Nginx:设置 client_max_body_size 20m;

站点 URL 设置不生效

确保在后台「系统设置 → 基础设置」中填写了完整的站点 URL(包含 http://https://),如 https://example.com/yue-album。保存后系统会优先使用此配置生成外链地址。

图片外链域名不对

在后台「系统设置 → 基础设置」中配置「图片域名及路径」字段。配置后所有图片的直链、HTML、Markdown、BBCode 都会使用此域名。例如配置 https://img.example.com/yue-album,则图片地址为 https://img.example.com/yue-album/uploads/2026/04/20/xxx.jpg

水印添加后透明区域变黑

这是 GD 库 imagecopymerge 的已知问题——该函数不支持 Alpha 通道。YueAlbum 已通过逐像素 Alpha 调整方式解决此问题。如果仍出现黑底,请确认水印图片是 PNG 格式且具有透明背景。

大图片上传/处理时出现 500 错误

通常是 PHP 内存不足。解决方案:

  1. 增大 memory_limit:在 .user.ini 中设置 memory_limit = 512M
  2. 系统会自动检测并尝试动态提升内存限制,但受 php.ini 全局配置约束
  3. 如果使用共享主机,可能无法调整 memory_limit,建议使用 VPS

Nginx 二级目录下路由不工作

确认 Nginx 配置中 try_files 指向了正确的 index.php

location /yue-album/ {
    try_files $uri $uri/ /yue-album/index.php?$query_string;
}

注意 $query_string 前的路径必须与实际部署路径一致。


许可

MIT License


悦·图床 YueAlbum — 轻量优雅,为图片而生。

About

由PHP8.4+Mysql开发的一款图床,轻量,易用可编写。

Language
PHP82.7%
CSS11.4%
JavaScript5.9%
HTML0.1%