PHP实现短域名互转的Memcache方案
本文将详细解析如何使用 PHP 语言结合 Memcache 分布式缓存,构建一套高效、可靠的短链接(Short URL)系统。通过 MD5 哈希确保重复 URL 的唯一性,并利用 Memcache 的原子递增操作分配自增 ID,最后将数字 ID 转换为 62 进制字符串作为短码前缀,实现长链到短链的双向转换。
原理与架构设计
短链接系统的核心在于建立“短码”与“完整 URL”之间的映射关系。本方案采用以下数据存储策略:
- 完整性校验:接收原始 URL 后,先计算其 MD5 值,作为唯一标识。
- 状态查询:检查 Memcache 中是否存在该 MD5 值的记录。若存在,说明该长链接已生成过短链接,直接返回旧短码即可,避免重复创建。
- 新链接生成:若为新链接,通过 Memcache 的
increment()方法对全局自增键进行累加,获取当前最新的唯一整数 ID。 - 双向映射存储:
- 以
MD5值为 Key,存储对应的ID(用于后续查找回放)。 - 以
ID转换成的短码为 Key,存储原始的URL(用于前端跳转访问)。
- 以
第1步:配置环境并初始化连接
首先需要实例化 Build_URL 类,并在构造函数中完成对 Memcache 服务器的集群连接配置。示例中配置了两个节点以确保可用性。
$mem_conf = array(
array(
'host' => '192.168.10.90',
'port' => '11116'
),
array(
'host' => '192.168.10.90',
'port' => '11117'
),
);
$this->mem = new Memcache();
foreach ($mem_conf as $v) {
$this->mem->addServer($v['host'], $v['port']);
}
第2步:实现短链接生成 (encode)
这是核心业务逻辑,处理 URL 验证、MD5 映射及自增 ID 转换。
- 输入验证:正则匹配确认 URL 以 http/https/ftp 开头。
- 冲突检测:查询 MD5 对应的 ID。
- 原子递增:若不存在,调用
$this->mem->increment('auto_increment_id')。若初始化为 False(说明首次运行),先设置初始值 10000,再重新递增,以防从零开始导致生成的短码过于冗长或格式不符预期。 - 编码转换:使用
dec2any()方法将整数 ID 转为 62 进制(0-9, a-z, A-Z)字符串。
public function encode($url) {
$url = trim($url);
// 简单的协议头校验
if(!preg_match("#^[http://|https://|ftp://]#iS", $url)) {
return false;
}
$md5 = md5($url);
$aid = $this->mem->get($md5);
if(!$aid) {
// 尝试获取下一个自增ID
if(($aid = $this->mem->increment('auto_increment_id')) === false) {
// 如果Memcache中没有这个Key(第一次运行),初始化为10000
$this->mem->set('auto_increment_id', 10000);
$aid = $this->mem->increment('auto_increment_id');
}
// 保存 MD5 -> ID 的映射,方便重复请求时复用
$this->mem->set($md5, $aid);
// 转换短码
$key = $this->dec2any($aid);
// 保存 短码 -> URL 的映射,用于跳转解码
$this->mem->set($key, $url);
} else {
// 已有记录,直接转换返回
$key = $this->dec2any($aid);
}
return $this->base_url.$key;
}
第3步:实现长链接解析 (decode)
解析过程相对简单,只需去除基础域名前缀,然后以留下的短码为 Key 从 Memcache 中取出原始 URL。
public function decode($url) {
$key = str_replace($this->base_url, '', trim($url));
return $this->mem->get($key);
}
第4步:基数转换算法 (dec2any)
为了缩短链接长度,采用 62 进制表示法将大整数转换为短字符串。算法原理类似于 Excel 列名的生成逻辑。
private function dec2any($num, $base=62, $index=false) {
$out = '';
if (! $base ) {
$base = strlen($index);
} else if (! $index ) {
// 定义字符集:数字+小写字母+大写字母
$index = substr("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base);
}
$t = ($num == 0) ? 0 : floor(log10($num) / log10($base));
for ($t; $t >= 0; $t--) {
$a = floor($num / pow( $base, $t ));
$out = $out . substr($index, $a, 1);
$num = $num - ($a * pow( $base, $t ));
}
return $out;
}
总结
上述代码提供了一个基于 PHP 和 Memcache 的最小可行性短链接服务实现。它利用了 Memcache 的高性能读写能力和原子操作特性,避免了数据库在高并发写入时的锁竞争问题。实际生产环境中,建议增加 Redis 持久化机制以防止重启数据丢失,并考虑引入负载均衡后的全局 ID 分配器(如雪花算法)以解决分布式场景下 Memcache 集群自增不一致的问题。
以上就是PHP实现短链接生成与解析的详细内容,更多关于PHP短域名转换的资料请关注本站其它相关文章!免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









