技术饭
PHP短网址生成逻辑与实现
微博短网址大家一定不陌生,如:http://t.cn/ 这个网站点开就直接跳转到了微博,是不是看起来很方便,但应该很多人都不知道是怎么实现的,我们今天就来讲讲PHP生成短网址的方法。
PHP生成短网址的:如果把短网址还原了,你知道是个什么样子的吗?可能你看到的短网址是这个样子:http://p-d-d.cn/T0f121,其实他还原了说不定就是这个样子:https://www.copylian.com/,按这个格式可以知道这个短网址其实是通过代码将长的网址:https://www.copylian.com/ 转成 http://p-d-d.cn/T0f121 ,然后短网址做个重定向到长网址就好了。
1、生成代码:
/**
* [shorturl 生成短网址]
* @param string $url [url]
* @param string $prefix [前缀]
* @param string $return_type [返回类型:url-返回url、code-返回code]
* @return [string] [短网址]
*/
function shorturl($url, $prefix = '', $return_type = 'url') {
//不存在则直接return
if (empty($url)) {
return;
}
//限制地址url长度为255
$url_len = mb_strlen($url);
if($url_len > 255){
return;
}
//查询表是否存在url
$where = [];
$where[] = ['url', '=', $url];
$shorturl = \Db::name('shorturl')->where($where)->findOrEmpty();
//如果存在则直接返回数据
if(!empty($shorturl) && !empty($shorturl['code'])){
if($return_type == 'url'){
//直接返回url
return config('common.shorturl_domain') . $shorturl['code'];
} else {
//直接返回code
return $shorturl['code'];
}
}
//加密
$crc32_url = crc32($url);
$crc32 = sprintf("%u", $crc32_url);
$show = '';
while ($crc32 > 0) {
$s = $crc32 % 62;
if ($s > 35) {
$s = chr($s + 61);
} elseif ($s > 9 && $s <= 35) {
$s = chr($s + 55);
}
$show .= $s;
$crc32 = floor($crc32 / 62);
}
//生成短网址码
$code = $prefix . $show;
//查询是否存在code,如果存在则直接更新url
$where = [];
$where[] = ['code', '=', $code];
$shorturl = \Db::name('shorturl')->where($where)->findOrEmpty();
if(!empty($shorturl)){
//更新数据
$update_data = [];
$update_data['id'] = $shorturl['id'];
$update_data['url'] = $url;
$update_data['code'] = $code;
$update_data['update_time'] = date("Y-m-d H:i:s");
$res = \Db::name('shorturl')->strict(false)->update($update_data);
} else {
//新增数据
$add_data = [];
$add_data['url'] = $url;
$add_data['code'] = $code;
$add_data['update_time'] = date("Y-m-d H:i:s");
$res = \Db::name('shorturl')->strict(false)->insert($add_data);
}
//返回数据
if($res){
if($return_type == 'url'){
//直接返回url
return config('common.shorturl_domain') . $code;
} else {
//直接返回code
return $code;
}
} else {
return;
}
}
2、数据库结构:
3、使用方法
生成:shorturl('https://www.copylian.com/', 0 , 'code')
结果:0T0f121
生成:shorturl('https://www.copylian.com/122', 1, 'code')
结果:1LXjc32
生成:shorturl('https://www.copylian.com/', '', 'url')
结果:http://p-d-d.cn/0T0f121
4、短网址处理代码:短网址的域名需要直接访问到这个shorturl方法
/**
* [shorturl 短网址]
*/
public function shorturl() {
//获取参数
$params = $this->request->param();
//验证
if(!isset($params['code']) && empty($params['code'])){
$rdata['code'] = 0;
$rdata['msg'] = '参数异常';
return json($rdata);
}
//查询短网址码
$where = [];
$where[] = ['code', '=', $params['code']];
$where[] = ['status', '=', 1];
$data = \Db::name('shorturl')->where($where)->findOrEmpty();
if(empty($data)){
$rdata['code'] = 0;
$rdata['msg'] = '网址不存在';
return json($rdata);
}
//直接重定向
return redirect($data['url']);
}
参考:
文明上网理性发言!