設計的主要問題,如何把一個url轉成一個6位的字串,且這些字串不允許衝突,比如不能讓兩個不同的url產生同一個字串
有的同學可能說直接md5然後截前6位,但是這樣很容出現衝突
可能有的同學說用一個index來累加,但是6位的只能表達999999個連結,明顯達不到要求,怎麼辦呢,筆者這裡給一個思路
既然是6位,那麼每位如果可能出現 0-9 a-z A-Z 就有 62的6次方種可能這樣能表達的最大值就是ZZZZZZ換算成十進位就是56800235584這麼多,夠用啦,如果到時候還是不夠,那咱們就升階到7位,永遠不用愁,其實咱們這裡就是設計了一個62進位的數,演算法實現如下
<?phpfunction 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的網域名稱配置模組中加入代碼
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