设计的主要问题,如何把一个url转成一个6位的字符串,且这些字符串不允许冲突,比如不能让两个不同的url生成同一个字符串
有的同学可能说直接md5然后截前6位,但是这样很容出现冲突
可能有的同学说用一个index来累加,但是6位的只能表达999999个链接,明显达不到要求,怎么办呢,笔者这里给一个思路
既然是6位,那么每位如果可能出现 0-9 a-z A-Z 就有 62的6次方种可能这样能表达的最大值就是ZZZZZZ换算成十进制就是56800235584这么多,够用啦,如果到时候还是不够,那咱们就升阶到7位,永远不用愁,其实咱们这里就是设计了一个62进制的数,算法实现如下
<?php function get_key_from_index($index) { $char_list = ['1','2','3','4','5','6','7','8','9', 'a','b','c','d','e','f','g','h', 'i','j','k','l','m','n','o','p','q', 'r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I', 'J','K','L','M','N','O','P','Q','R', 'S','T','U','V','W','X','Y','Z']; if($index==0) { return 0; } if($index<=count($char_list)) { return $char_list[$index-1]; } $result = ''; while(true){ $remain = $index%62; $result = get_key_from_index($remain).$result; $index = intval($index/62); if($index<62) { $result = get_key_from_index($index).$result; break; } } return $result; }
然后我们就需要一个计数器,这里简单选redis
function get_short_key(){ #$index = $redis->incr('short_url_index'); $key = get_key_from_index(1000); echo sprintf("%06s",$key); } echo get_short_key();
生成短链接key大功告成,记得存到mysql的时候编码选utf8_bin,如果选了utf8_gen_ci这个不会区分大小写,注意喽
第二步,我们的最终目标是http://域名/a0Z3d4 这种格式,这种直接访问就404,所有我们的nginx需要配一下
在nginx的域名配置模块中加入代码
扫描二维码关注公众号,回复:
822498 查看本文章
server { listen 80; server_name t.cn; index index.html index.htm index.php; root /Users/www/rsf/app-web; #注意这里是关键,所有请求转发到index.php rewrite . /index.php; location ~ .*\.(php|php5)?$ { fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
然后我们在index.php中获取request_uri就可以得到这个字符串了
这种代码就不用贴了吧
over