同学录网站制作遇坑记:你也有这样的遭遇吗?

最近闲得蛋疼,突然想搞个同学录网站怀旧一下。结果发现网上那些现成的要么收费,要么丑得像我高中班主任的地中海发型。得,自己动手丰衣足食,抄起键盘就开始撸代码。现在把这段充满bug的旅程记录下来,给后来者当个反面教材也好。

先说下技术选型这个坑。本来想用Python装个逼,结果发现虚拟主机只支持PHP。行,PHP就PHP,反正这东西写起来跟写作文似的,就是容易写出"屎山"。数据库用的MySQL,别问为什么不用MongoDB,问就是穷。

先来看用户表结构,这个设计让我掉了不少头发:

CREATE TABLE users (

id int(11) NOT NULL AUTO_INCREMENT,

username varchar(50) NOT NULL,

password char(60) NOT NULL COMMENT '用password_hash加密',

real_name varchar(20) DEFAULT NULL,

class_id int(11) DEFAULT NULL,

avatar varchar(255) DEFAULT 'default.jpg',

graduate_year year(4) DEFAULT NULL,

created_at timestamp NOT NULL DEFAULT current_timestamp(),

PRIMARY KEY (id),

UNIQUE KEY username (username)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这里有个坑,密码字段长度一定要设60,因为password_hash出来的字符串固定60个字符。别问我怎么知道的,我当初设了50,结果用户注册时数据库默默把密码截断了,登录时永远提示密码错误,debug到怀疑人生。

登录验证这块我用了最朴素的session方案:

session_start();

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

$username = trim($_POST['username']);

$password = $_POST['password'];

$stmt = $pdo->prepare("SELECT id, password FROM users WHERE username = ?");

$stmt->execute([$username]);

$user = $stmt->fetch();

if ($user && password_verify($password, $user['password'])) {

$_SESSION['user_id'] = $user['id'];

header('Location: /home.php');

exit;

} else {

$error = "用户名或密码错误";

}

}

注意那个trim(),有用户反映用户名后面加空格登录不了。这让我想起当年暗恋的班花,她名字后面也总是跟着一群追求者,像极了字符串后面的空格。

同学录的核心功能当然是留言板。这个看似简单的功能让我踩了三个大坑:

1. XSS攻击:刚开始直接echo用户输入,结果有个调皮的同学写了段js代码,把页面搞得跟迪厅似的闪个不停

2. SQL注入:最早用字符串拼接SQL,直到有人留言内容里带了个单引号,整个站就嗝屁了

3. 表情符号支持:00后学弟学妹们不用emoji会死,MySQL的utf8居然存不了,得用utf8mb4

修正后的留言插入代码长这样:

$content = htmlspecialchars($_POST['content'], ENT_QUOTES);

$stmt = $pdo->prepare("INSERT INTO messages (user_id, content, created_at) VALUES (?, ?, NOW())");

$stmt->execute([$_SESSION['user_id'], $content]);

照片上传功能堪称血泪史的高潮部分。我天真地以为move_uploaded_file()就完事了,结果:

有同学上传了10MB的毕业照,直接把服务器撑爆

有人传了.php文件,差点把我服务器变成肉鸡

图片重名直接覆盖,引发多起"你凭什么删我照片"的战争

最终的上传代码臃肿得像过年回家的行李箱:

$allowed_types = ['image/jpeg', 'image/png'];

$max_size = 2 1024 1024; // 2MB

if (in_array($_FILES['photo']['type'], $allowed_types) &&

$_FILES['photo']['size'] <= $max_size) {

$ext = pathinfo($_FILES['photo']['name'], PATHINFO_EXTENSION);

$filename = uniqid() . '.' . $ext;

$path = 'uploads/' . $filename;

if (move_uploaded_file($_FILES['photo']['tmp_name'], $path)) {

// 更新用户头像

$stmt = $pdo->prepare("UPDATE users SET avatar = ? WHERE id = ?");

$stmt->execute([$filename, $_SESSION['user_id']]);

}

分页功能让我深刻理解了什么叫"理想很丰满,现实很骨感"。第一版分页我写了50行代码,后来发现用SQL的LIMIT和OFFSET就能解决:

$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;

$per_page = 10;

$offset = ($page - 1) $per_page;

$stmt = $pdo->prepare("SELECT FROM messages ORDER BY id DESC LIMIT ? OFFSET ?");

$stmt->execute([$per_page, $offset]);

但是!这里有个巨坑:MySQL的预处理语句对LIMIT参数的处理很奇葩,得改成这样:

$stmt->bindValue(1, $offset, PDO::PARAM_INT);

$stmt->bindValue(2, $per_page, PDO::PARAM_INT);

$stmt->execute();

搜索功能本来想用LIKE糊弄过去,直到有人搜"张",结果把所有带"张"字的留言都搜出来了,包括"紧张"、"开张"、"嚣张"。最后被迫上了全文索引:

ALTER TABLE messages ADD FULLTEXT INDEX ft_content (content);

$keyword = $_GET['q'];

$stmt = $pdo->prepare("SELECT * FROM messages WHERE MATCH(content) AGAINST(? IN BOOLEAN MODE)");

$stmt->execute([$keyword]);

部署时遇到的坑够写本《悲惨世界》续集:

1. 文件权限问题:上传目录要755,我设成777后被警告存在安全风险

2. PHP版本问题:本地用7.4开发,服务器是5.6,password_hash函数直接罢工

3. 时区问题:所有时间显示"现在",原来是忘了设date_default_timezone_set

最后的最后,给后来者几个忠告:

永远不要相信用户输入,过滤、验证、转义三件套不能少

错误日志要开,但别把错误信息直接展示给用户

数据库操作一定要用预处理语句

上传文件要限制类型和大小

PHP版本最好用7.0以上,别学我用5.6自虐

这个同学录网站现在跑得还算稳当,虽然界面丑得像90年代的QQ空间。但有什么关系,就像我们班当年的毕业照,再丑也是青春。代码虽然糙,但好歹是自己一砖一瓦垒起来的,比那些花里胡哨的框架更有温度。

内容概要:本文档是一份计算机软考初级程序员的经典面试题汇编,涵盖了面向对象编程的四大特征(抽象、继承、封装、多态),并详细探讨了Java编程中的诸多核心概念,如基本数据类型与引用类型的区别、String和StringBuffer的差异、异常处理机制、Servlet的生命周期及其与CGI的区别、集合框架中ArrayList、Vector和LinkedList的特性对比、EJB的实现技术及其不同Bean类型的区别、Collection和Collections的差异、final、finally和finalize的作用、线程同步与异步的区别、抽象类和接口的区别、垃圾回收机制、JSP和Servlet的工作原理及其异同等。此外,还介绍了WebLogic服务器的相关配置、EJB的激活机制、J2EE平台的构成和服务、常见的设计模式(如工厂模式)、Web容器和EJB容器的功能、JNDI、JMS、JTA等J2EE核心技术的概念。 适合人群:正在备考计算机软考初级程序员的考生,或希望加深对Java编程及Web开发理解的初、中级开发人员。 使用场景及目标:①帮助考生系统复习Java编程语言的基础知识和高级特性;②为实际项目开发提供理论指导,提升编程技能;③为面试准备提供参考,帮助求职者更好地应对技术面试。 其他说明:文档不仅涉及Java编程语言的核心知识点,还包括了Web开发、企业级应用开发等方面的技术要点,旨在全面提高读者的专业素养和技术水平。文档内容详实,适合有一定编程基础的学习者深入学习和研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值