PHP实现短域名互转的Memcache方案

蓝鲸
蓝鲸
发布时间:2026-10-14 | 4人浏览过
原创

本文将详细解析如何使用 PHP 语言结合 Memcache 分布式缓存,构建一套高效、可靠的短链接(Short URL)系统。通过 MD5 哈希确保重复 URL 的唯一性,并利用 Memcache 的原子递增操作分配自增 ID,最后将数字 ID 转换为 62 进制字符串作为短码前缀,实现长链到短链的双向转换。

原理与架构设计

短链接系统的核心在于建立“短码”与“完整 URL”之间的映射关系。本方案采用以下数据存储策略:

  1. 完整性校验:接收原始 URL 后,先计算其 MD5 值,作为唯一标识。
  2. 状态查询:检查 Memcache 中是否存在该 MD5 值的记录。若存在,说明该长链接已生成过短链接,直接返回旧短码即可,避免重复创建。
  3. 新链接生成:若为新链接,通过 Memcache 的 increment() 方法对全局自增键进行累加,获取当前最新的唯一整数 ID。
  4. 双向映射存储:
    • 以 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短域名转换的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表