本文目录导读:

在PHP中生成短地址(短链接)有多种算法,我来介绍几种常用的方案:
基于MD5的短地址算法(最常用)
<?php
class ShortUrlGenerator {
/**
* 生成短地址
* @param string $url 原始URL
* @param int $length 短地址长度
* @return array 返回多个短地址
*/
public static function generate($url, $length = 8) {
// 创建MD5哈希
$md5 = md5($url);
$shortUrls = [];
// 通常生成4个短地址供选择
for ($i = 0; $i < 4; $i++) {
// 从MD5中取一段,每8个字符一组
$segment = substr($md5, $i * 8, 8);
// 将16进制转为10进制
$hexdec = hexdec($segment);
// 使用62进制编码
$shortUrl = self::base62Encode($hexdec);
// 截取指定长度
$shortUrls[] = substr($shortUrl, 0, $length);
}
return $shortUrls;
}
/**
* 10进制转62进制
*/
private static function base62Encode($num) {
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$result = '';
while ($num > 0) {
$result = $chars[$num % 62] . $result;
$num = floor($num / 62);
}
return $result;
}
}
// 使用示例
$url = 'https://www.example.com/article/123456?ref=homepage';
$shortUrls = ShortUrlGenerator::generate($url);
print_r($shortUrls);
// 输出类似:Array ( [0] => b60e7qKb [1] => 0Qf9HqF6 [2] => 3MaF7sT8 [3] => 9vN4cDmX )
?>
自增ID + 字母数字编码算法
<?php
class ShortUrlService {
private $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
private $base = 62;
/**
* 将数字ID转换为短码
* @param int $id 自增ID
* @return string 短码
*/
public function encode($id) {
$shortUrl = '';
while ($id > 0) {
$shortUrl = $this->alphabet[$id % $this->base] . $shortUrl;
$id = floor($id / $this->base);
}
// 如果结果为空,返回第一个字符
if (empty($shortUrl)) {
$shortUrl = $this->alphabet[0];
}
return $shortUrl;
}
/**
* 将短码解码为数字ID
* @param string $code 短码
* @return int 原始ID
*/
public function decode($code) {
$id = 0;
$len = strlen($code);
for ($i = 0; $i < $len; $i++) {
$id = $id * $this->base + strpos($this->alphabet, $code[$i]);
}
return $id;
}
}
// 使用示例
$service = new ShortUrlService();
// 假设数据库中URL的自增ID
$id = 1000000;
$shortCode = $service->encode($id);
echo "短码: " . $shortCode . "\n"; // 输出类似: 4c92
// 解码验证
$decodedId = $service->decode($shortCode);
echo "解码后的ID: " . $decodedId . "\n";
?>
基于随机数的短地址算法
<?php
class RandomShortUrl {
private $length = 8;
/**
* 生成随机短码
* @param int $length
* @return string
*/
public function generateRandom($length = null) {
$length = $length ?: $this->length;
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
// 使用密码学安全的随机数生成器
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[random_int(0, $charactersLength - 1)];
}
return $randomString;
}
/**
* 检查短码是否已存在(需实现已使用短码的存储)
*/
public function generateUnique() {
do {
$code = $this->generateRandom();
// 这里需要检查数据库中是否已存在该短码
// $exists = $this->checkExistsInDB($code);
$exists = false; // 假设不存在
} while ($exists);
return $code;
}
}
// 使用示例
$generator = new RandomShortUrl();
$shortCode = $generator->generateRandom(6);
echo "随机短码: " . $shortCode . "\n";
?>
完整示例:包含数据库操作的短链接系统
<?php
class ShortLinkSystem {
private $db;
private $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
private $base = 62;
public function __construct($host, $user, $pass, $dbname) {
// 数据库连接示例(使用PDO)
$this->db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
/**
* 创建短链接
*/
public function createShortLink($originalUrl) {
// 1. 将URL插入数据库,获取自增ID
$stmt = $this->db->prepare("INSERT INTO urls (original_url, created_at) VALUES (?, NOW())");
$stmt->execute([$originalUrl]);
$id = $this->db->lastInsertId();
// 2. 生成短码
$shortCode = $this->encode($id);
// 3. 更新记录的短码
$stmt = $this->db->prepare("UPDATE urls SET short_code = ? WHERE id = ?");
$stmt->execute([$shortCode, $id]);
return $shortCode;
}
/**
* 解析短链接
*/
public function getOriginalUrl($shortCode) {
$stmt = $this->db->prepare("SELECT original_url FROM urls WHERE short_code = ?");
$stmt->execute([$shortCode]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result) {
// 更新访问次数
$this->updateClickCount($shortCode);
return $result['original_url'];
}
return null;
}
/**
* 更新点击次数
*/
private function updateClickCount($shortCode) {
$stmt = $this->db->prepare("UPDATE urls SET clicks = clicks + 1 WHERE short_code = ?");
$stmt->execute([$shortCode]);
}
/**
* ID转短码
*/
private function encode($id) {
$shortCode = '';
while ($id > 0) {
$shortCode = $this->alphabet[$id % $this->base] . $shortCode;
$id = floor($id / $this->base);
}
return $shortCode;
}
/**
* 短码转ID
*/
private function decode($code) {
$id = 0;
$len = strlen($code);
for ($i = 0; $i < $len; $i++) {
$id = $id * $this->base + strpos($this->alphabet, $code[$i]);
}
return $id;
}
}
// 使用示例
// $system = new ShortLinkSystem('localhost', 'root', '', 'short_url');
// $shortCode = $system->createShortLink('https://www.example.com/very/long/url');
// $originalUrl = $system->getOriginalUrl($shortCode);
?>
使用现成库:Guzzle + RandomLib
<?php
// 使用 Composer 安装库
// composer require paragonie/random_compat
// 组合使用多种算法生成短码
function generateShortUrl($url, $length = 6) {
// 方法1:MD5 + base62
$md5 = md5($url . time() . rand(10000, 99999));
$hexdec = hexdec(substr($md5, 0, 8));
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$short = '';
while ($hexdec > 0) {
$short = $chars[$hexdec % 62] . $short;
$hexdec = floor($hexdec / 62);
}
// 截取指定长度
return substr($short, 0, $length);
}
?>
注意事项
- 冲突处理:确保生成的短码在数据库中唯一,需要检查重复
- 安全考虑:使用
random_int()而不是rand()生成随机数 - 性能优化:对热点短码进行缓存(Redis/Memcached)
- 数据库索引:短码字段应该建立唯一索引
- URL验证:生成前验证原始URL的格式
- 自定义短码:允许用户自定义短码,但需检查可用性
选择哪种算法取决于你的具体需求:
- 自增ID算法:短码长度固定,可预测,适合内部系统
- 随机算法:不可预测,安全性更高,适合公开服务
- MD5算法:基于原始URL生成,可重复生成相同短码
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播