前言
作为一个热爱编程和数字内容创作的个人开发者,我一直希望拥有一个属于自己的网站——既能展示自己开发的软件和小工具,又能与用户互动、沉淀内容。然而,市面上的CMS(内容管理系统)要么过于臃肿,要么定制成本太高。于是,我决定从零开始,手写一套简洁但功能完整的软件分享平台。本文将完整记录这个网站的策划、开发、优化全过程,包括技术选型、核心模块实现、踩坑与解决等,希望能为同路者提供一些参考。

一、项目背景与需求分析
1.1 为什么要自己写?
最初我尝试过WordPress,但插件臃肿、主题定制麻烦,而且我希望网站具备软件发布、下载统计、留言板、广告位管理、多平台社交登录、用户系统等一体化功能,与其拼凑插件,不如从底层构建一套专属于自己的系统。
1.2 核心需求清单
- 软件管理:支持后台添加/编辑软件,包括名称、版本、体积、截图、介绍(富文本)、下载链接(本站/网盘/自定义)。
- 用户系统:普通注册(邮箱验证)+ 社交登录(QQ、微博、支付宝),支持个人中心(修改头像/昵称/邮箱/密码)。
- 留言板:访客留言(分类、职业、城市等),后台审核。
- 广告系统:支持短代码(如
[AD1])在任意位置插入广告,且广告容器样式统一管理。 - 全站搜索:搜索软件标题、关键词、描述。
- 公告系统:首页滚动显示公告,点击弹窗查看详情。
- 响应式设计:电脑、平板、手机自适应。
- SEO友好:自定义标题、描述、关键词、伪静态URL。
这些需求决定了后端需要较为完整的CRUD,前端需要良好的交互体验。
二、功能全景概览
为方便读者快速了解网站的核心能力,我将主要功能分为前台(用户可见) 和后台(管理员) 两大类进行说明。
前台功能
软件浏览与搜索
-
- 首页按时间倒序展示最新软件卡片(含图标、标题、简短描述)。
- 软件分类页支持按分类筛选,采用长条卡片布局,展示软件分类、浏览次数、关键词等信息。
- 全站搜索可检索软件标题、关键词、详细介绍,并记录搜索日志。
软件详情页
-
- 显示完整软件信息:适用平台、版本、体积、作者、下载链接(本站/网盘/自定义)、软件截图、详细介绍。
- 支持富文本图文混排,右侧推荐同类软件和广告位。
- 自动记录浏览次数和下载次数。
用户系统
-
- 普通注册:填写邮箱获取验证码,设置密码,完成邮箱验证。
- 社交登录:支持QQ、微博、支付宝一键登录(无需单独注册)。
- 个人中心:可修改头像(上传图片)、昵称、邮箱、密码,查看注册时间和上次登录时间。
留言板
-
- 访客可填写姓名、性别、职业、城市、留言类型(购买咨询、功能设想等)、留言内容,所有留言需后台审核后显示。
- 前台展示留言时会显示用户昵称、城市、职业、留言分类和时间。
公告系统
-
- 首页顶部滚动显示最新公告标题,点击弹出模态框展示完整内容(支持HTML)。
- 管理员后台可随时添加、编辑、删除公告,并可选择是否启用。
其他辅助功能
-
- 全站搜索框位于页眉菜单下方,支持关键词模糊匹配。
- 右下角浮动图标组包含“回到顶部”和自定义社交链接(QQ、微信、微博)。
- 页脚显示网站备案信息、版权声明和简单计数器。
后台管理功能
- 仪表盘:展示软件总数、待审留言数、合作洽谈记录数等统计。
- 软件管理:完整的CRUD,支持上传图标、截图、软件文件(本站下载),网盘下载需填写链接和提取码,自定义下载可填任意URL。
- 分类管理:增删改软件分类,支持排序和别名(slug)自动生成唯一性检查。
- 留言管理:查看、审核、删除留言,支持搜索和分页。
- 广告管理:添加/编辑短代码广告(如[AD1]),指定投放位置(详情页侧边栏、软件分类页内等),支持HTML/JS代码。
- 公告管理:添加/编辑/启用/禁用公告,内容支持TinyMCE富文本编辑器。
- 用户管理:查看所有注册用户,可禁用、启用、删除用户,也可直接编辑用户昵称、邮箱、密码。
- 系统设置:配置浮动社交链接、敏感词过滤、邮件服务器(SMTP)、开发计划与关于我们的富文本内容。
- 邮件设置:独立配置SMTP参数(用于注册验证码和合作洽谈邮件)。
- 管理员管理:超级管理员可增删普通管理员。
三、技术架构与数据库设计
3.1 技术栈
- 后端:PHP 8.2 + MySQL 8.0,采用原生PDO操作数据库,没有使用框架(便于灵活控制)。
- 前端:原生HTML/CSS/JS + TinyMCE富文本编辑器 + 自定义模态框。
- 服务器:Nginx + PHP-FPM,宝塔面板管理。
3.2 数据库核心表设计
以软件表 zhuoying_software 为例:
CREATE TABLE `zhuoying_software` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(200) NOT NULL, `short_title` varchar(200) DEFAULT NULL, `category_id` int(11) NOT NULL, `platform` varchar(100) DEFAULT NULL, `version` varchar(50) DEFAULT NULL, `size_bytes` varchar(100) DEFAULT NULL, `author` varchar(100) DEFAULT '卓影工作室', `keywords` varchar(500) DEFAULT NULL, `description` text, `image` varchar(500) DEFAULT NULL, `icon` varchar(500) DEFAULT NULL, `status` tinyint(1) DEFAULT 2, `download_type` enum('local','pan','custom') NOT NULL, `local_file` varchar(500) DEFAULT NULL, `pan_url` varchar(500) DEFAULT NULL, `pan_code` varchar(50) DEFAULT NULL, `custom_url` varchar(500) DEFAULT NULL, `downloads` int(11) DEFAULT 0, `views` int(11) DEFAULT 0, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) );
用户表 zhuoying_users 除了基础字段,还预留了 qq_openid、weibo_uid、alipay_user_id 用于社交登录。配置表 zhuoying_options 以键值对形式存储系统设置(SMTP、社交登录密钥、广告短代码内容等),避免了频繁修改文件。
四、核心功能实现与难点攻克
4.1 软件管理:富文本编辑器与文件上传
后台软件编辑页面采用左右两栏布局,左侧是标题、截图、详细内容(TinyMCE),右侧是分类、关键词、下载设置等。其中最棘手的是图片上传:既要支持从本地上传(作为软件截图),又要支持在编辑器中拖拽/选择图片。我写了一个统一的 uploadFile() 函数处理上传,并利用 TinyMCE 的 images_upload_handler 实现编辑器内图片上传。
function uploadFile($file, $targetDir, $allowed = [...]) { if ($file['error'] !== UPLOAD_ERR_OK) return null; $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($ext, $allowed)) return null; $filename = time() . '_' . uniqid() . '.' . $ext; $dest = $targetDir . $filename; if (!is_dir($targetDir)) mkdir($targetDir, 0755, true); return move_uploaded_file($file['tmp_name'], $dest) ? $filename : null; }
同时为了保留原文件名(避免重复),加入了自动重命名逻辑。上传的图片统一保存到 /uploads/software/ 或 /uploads/ckeditor/ 目录。
4.2 用户系统:注册 + 邮箱验证 + 社交登录
普通注册要求填写邮箱并发送验证码,使用 PHPMailer 通过 SMTP 发送。验证码存储在 session 中,用户提交时验证。代码片段:
use PHPMailer\PHPMailer\PHPMailer; $mail = new PHPMailer(true); $mail->isSMTP(); $mail->Host = $smtp['host']; $mail->SMTPAuth = true; $mail->Username = $smtp['username']; $mail->Password = $smtp['password']; $mail->setFrom($smtp['from_email'], $smtp['from_name']); $mail->addAddress($email); $mail->Body = "您的验证码是:{$code}"; $mail->send();
社交登录集成QQ、微博、支付宝的OAuth 2.0流程。回调后获取用户唯一标识,如果不存在则跳转到完善资料页面(填写邮箱、设置密码),否则直接登录。
4.3 广告短代码系统
为了方便在任意位置插入广告,我设计了一个简单的短代码解析器。在 inc/functions.php 中:
function parse_ad_shortcodes($content) { global $pdo; static $ads = null; if ($ads === null) { $stmt = $pdo->query("SELECT code, content FROM zhuoying_ads WHERE is_active=1"); $ads = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); } foreach ($ads as $code => $html) { $content = str_replace($code, $html, $content); } return $content; }
管理员在后台添加广告时只需填写短代码(如 [AD1])和广告代码(HTML/JS),前端输出内容时自动替换。同时样式由 .sidebar-ad-box 统一控制,保证了视觉一致性。
五、细节优化与问题解决
5.1 会话管理:一个容易被忽略的坑
网站出现“登录后仍然显示登录按钮”的 bug,排查发现是 inc/config.php 中缺少 session_start()。因为后台和前台都需要会话,我在配置文件中统一启动,并添加了 if (session_status() === PHP_SESSION_NONE) 判断,避免重复启动。
5.2 文件上传权限问题
Linux 环境下,uploads 目录必须赋予 Web 用户写权限。使用命令:
sudo chown -R www:www /www/wwwroot/sjinyu.com/uploads sudo chmod -R 755 /www/wwwroot/sjinyu.com/uploads
同时 PHP 配置中需要调整 upload_max_filesize 和 post_max_size 以支持较大文件。
5.3 富文本编辑器中文语言包路径
TinyMCE 需要手动下载中文语言包并放置到指定目录,初始化时指定 language_url: '/TinyMCE/langs/zh_CN.js'。看似小问题,但不配置的话工具栏全是英文,不够友好。
5.4 CSS 样式统一与响应式
从最初黑色科技风主页到后来白色卡片式详情页,经历了多次迭代。最终采用全局 style.css + 页面专用 software-detail.css 的方式分离样式,并利用媒体查询处理移动端布局。例如卡片网格在 PC 端显示 4 列,平板 2 列,手机 1 列:
.apps-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; } @media (max-width: 768px) { .apps-grid { grid-template-columns: 1fr; } }
5.5 规避安全软件误报
开发过程中,腾讯云安全曾误报 upload_image.php、contact.php 等文件为恶意,原因是使用了 move_uploaded_file 和 mail() 等敏感函数。解决方案是将网站目录加入白名单,并确保代码无注入漏洞。
六、总结与展望
历时一周的密集开发,这个网站终于从一张白纸变成了一个功能完整的软件分享平台。主要成果覆盖了文章第二节所述的全部功能,并已上线运行。
当然,也有一些遗憾待完善:例如未实现评论系统、用户之间私信、积分下载等。未来可以考虑增加这些功能,并进一步优化前端用户体验。
结语
从零手写一个网站的过程,不仅是技术的一次实践,更是一次对产品思维的打磨。每一处细节——从数据库字段命名到表单的边距对齐——都影响着最终的使用感受。希望这篇记录能给正在考虑自己建站的你一点启发。如果你对代码有任何疑问,欢迎访问我的网站留言交流。
卓影数字传媒工作室:https://www.sjinyu.com

