短链接生成的核心逻辑是将自增ID通过Base62编码为固定长度字符串,而非随机生成或哈希截断;需保证可逆、防冲突(加唯一索引)、防开放重定向,并记录元数据以支持追溯与统计。

短链接生成的核心逻辑是什么
短链接不是靠随机字符串“凑”出来的,而是把原始 URL 做哈希或自增 ID 编码后映射成固定长度的字符串。直接用 md5() 或 sha1() 截取前 6 位看似简单,但冲突概率高、不可逆、无法追踪;更稳妥的做法是用「自增主键 + 进制转换」,比如把数据库里刚插入的 id(10 进制)转成 62 进制(a–z, A–Z, 0–9)。
用 base62 编码实现可逆短码
php 没有内置 base62,但逻辑极简:不断对 ID 取模 62,查表拼字符。注意别漏掉 0 的处理,否则 id=0 会生成空字符串。
function idToShort($id) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; if ($id == 0) return 'a'; // 映射 0 → 'a' $short = ''; while ($id > 0) { $short = $chars[$id % 62] . $short; $id = (int)($id / 62); } return $short; }
反向解码时按权展开即可,关键点:$id = $id * 62 + strpos($Chars, $char)。务必校验输入字符是否全在 $chars 中,否则可能静默出错。
数据库必须加唯一索引防重复
即使编码逻辑完美,高并发下两个请求同时拿到相同 id 并生成相同短码的情况极少,但插入前没校验、没索引就会导致数据错乱或报错 Integrity constraint violation。
立即学习“PHP免费学习笔记(深入)”;
- 建表时给
short_code字段加UNIQUE索引 - 插入失败时捕获
23000错误码(mysql),重试编码下一个id - 避免用
select ... for UPDATE锁表,性能差且易死锁
跳转时如何安全重定向
收到短码请求后,先查库获取原 URL,再用 header('location: ...', true, 302) 跳转。这里有两个硬性要求:
- 必须检查查到的
original_url是否以http://或https://开头,否则拒绝跳转,防止开放重定向漏洞 - 必须在
header()前确保无任何输出(包括空格、bom、echo),否则报错Cannot modify header information - 建议加
exit;防止后续代码执行
真正难的不是生成那几行代码,而是怎么让每次生成都可追溯、不冲突、不被滥用——短码表里至少得存 id、short_code、original_url、created_at 和 click_count,少一个字段后期就容易卡住。