核心是Base62编码自增ID或随机生成+唯一索引校验生成不冲突短码,存储映射关系并记录IP、来源、时间等元数据后302跳转,路由需严格校验短码格式,跳转前校验过期与访问上限,日志表须截断长字段防溢出。

要让PHP框架生成可追踪跳转行为的短链接,核心是把原始URL映射为唯一短码,并在用户访问短链接时记录来源、时间、IP等信息再302重定向。整个流程必须保证短码不冲突、跳转不丢失参数、追踪数据可查。
生成唯一短码
方法一:Base62编码+自增ID(推荐用于MySQL主键场景)
第一步:插入原始URL到数据库,获取自增ID(如123456);
第二步:将ID转为Base62字符串——用字符集0-9a-zA-Z共62个字符循环取余拼接;
第三步:截取前6位作为短码(如qR8xK2),检查是否已存在,若存在则ID+1重试;
这一步必须加数据库唯一索引约束,否则并发插入可能生成重复短码。
方法二:随机生成+去重校验(适合无主键依赖或分布式环境)
用random_bytes(3)生成3字节二进制,转hex后取前6位→substr(bin2hex(random_bytes(3)), 0, 6);
生成后立即查表确认short_code字段不存在,否则循环重试;
【最多尝试10次未成功就抛出异常,避免死循环】;
该方式无需依赖数据库自增,但需配合Redis原子计数器或DB唯一索引防碰撞。
存储映射关系与元数据
建一张short_urls表,字段至少包含:id(主键)、short_code(唯一索引)、original_url(TEXT)、created_at、expires_at(可空)、max_visits(可空)。
插入时务必对original_url做filter_var($url, FILTER_VALIDATE_URL)校验,防止SQL注入或跳转到javascript:伪协议。
若原始URL含中文或特殊符号,入库前用rawurlencode()编码,读取重定向时不再二次encode,避免双重编码乱码。
立即学习“PHP免费学习笔记(深入)”;
路由注册与跳转响应
Laravel示例:在routes/web.php中添加Route::get('/{code}', [ShortLinkController::class, 'redirect'])->where('code', '[a-zA-Z0-9]{4,12}');;
ThinkPHP示例:配置路由规则'__pattern__/code' => '\w{4,12}',绑定到Index/shortJump方法;
注意{code}正则必须限制长度和字符集,否则攻击者可能传入../.env触发路径遍历。
控制器中先根据$code查short_urls表,查不到返回404;
查到后检查expires_at是否过期、max_visits是否已达上限;
满足条件则执行$this->recordVisit($code, $request)写入访问日志表,再返回header("Location: ".$url); exit;;
【必须用header()而非框架redirect(),避免中间件干扰或额外cookie写入】。
记录跳转行为
新建short_url_visits表,字段包括:short_code、ip、user_agent、referer、created_at、query_string(存原始GET参数,便于还原带参跳转);
写入前对$_SERVER['HTTP_REFERER']和$_SERVER['HTTP_USER_AGENT']做mb_substr(..., 0, 512)截断,防止超长UA撑爆字段;
IP提取用$_SERVER['REMOTE_ADDR'],若前端有Nginx反向代理,需改用$_SERVER['HTTP_X_REAL_IP']并验证其可信性。



















