說到短網址,那什麼是短網址呢?
短網址(Short URL) ,顧名思義就是在形式上比較短的網址。通常用的是asp或者php轉向,在Web 2.0的今天,不得不說,這是一個潮流。目前已經有許多類似服務,借助短網址您可以用簡短的網址替代原來冗長的網址,讓使用者可以更容易的分享連結。【摘自百度百科】
如何将長網址變成短網址?
很多人有疑問,短網址的存在到底有什麼意義呢?這個問題在移動網際網路時代還未開始的時候,真的很難回答,但是如今,我相信沒有人不知道短網址存在的重要性了。因為很多很多人都在日常生活中能見到短連結。據不完全統計,目前移動流量已經遠遠超越了PC流量,不得不承認現在是移動網際網路的時代。我身邊很多朋友告訴我,他們基本上幾個月才會用一次電腦,有的甚至一年都沒有用過PC電腦。電腦開機率越來越低,是因為随着移動網際網路時代的到來,生活中越來越多的問題可以直接用手機解決。甚至出現了很多新的名詞:低頭族。雖然這種說話帶有點貶義,但是非常符合目前的現狀。手機已經成了生活照必不可少的物品,但你離開家的時候,都會下意識的摸摸口袋是否帶了手機,手機是否有電等等。
移動網際網路時代雖然已經到來,移動裝置主宰着我們的生活,但是電池技術的局限,很多移動裝置的螢幕不可能做的很大。在有限的螢幕内,為了提升使用者體驗必須要縮短網址,這個時候,短網址就成了不可或缺的重要手段。
它的原理也很簡單,使用HTTP 301 Moved狀态碼重定向,浏覽器就會自動的轉向到目标網址。這個實作起來的難度不大,代價也不會很高。因為多了這一次轉發,這使得那些被傳播的網址多了一些可控的因素,比如說可以記錄請求的封包,對來源網站、IP、浏覽器等許多資訊進行收集和統計;可以針對有害網站進行跳轉前的過濾和警告。這樣子,一個連接配接投放出去之後的效果就可以很友善的統計。
我們現在直接走代碼模拟一下短網址的功能
先建一個資料庫,我這裡取名為s5ip,再建一張表,我取名為web
CREATE TABLE `web` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
`short_website` varchar(50) NOT NULL COMMENT '短網址',
`long_website` varchar(300) NOT NULL COMMENT '原網址',
`times` int(10) unsigned DEFAULT '1' COMMENT '通路次數',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
設定一個虛拟域名,我這裡是取名為http://s5ip.cn
index.php代碼
<?php
include "s5ip.php";
?>
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8" />
<link href="https://cdn.bootcdn.net/npm/[email protected]/dist/css/bootstrap.min.css" target="_blank" rel="external nofollow" rel="stylesheet">
<title>短網址案例</title>
<style type="text/css">
.box{
padding-top: 50px;
}
.box .form-inline{
text-align: center;
}
.box .website-div{
margin-top: 10px;
}
.box .website-name{
margin-left: 25px;
}
.box .website-value{
margin-left: -40px;
}
.box .website{
width: 567px !important;
}
.box .transfer-div{
margin-bottom: 10px;
}
.box .error{
margin-left: 10px;
color: red;
}
</style>
</head>
<body>
<div class="container box">
<div class="transfer-div">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">縮短網址</div>
<input type="text" class="form-control website" placeholder="輸入網址,如:http://www.baidu.com" value="https://cdn.bootcdn.net/npm/[email protected]/dist/jquery.min.js">
</div>
</div>
<button type="button" class="btn btn-primary transfer">縮短</button><span class="error" hidden></span>
</form>
<div class="row website-div" hidden>
<div class="col-md-2"></div>
<div class="col-md-1 website-name">原網址:</div>
<div class="col-md-9 website-value long-website"></div>
</div>
<div class="row website-div" hidden>
<div class="col-md-2"></div>
<div class="col-md-1 website-name">短網址:</div>
<div class="col-md-9 website-value short-website"></div>
</div>
</div>
<div class="transfer-div">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">還原網址</div>
<input type="text" class="form-control website" placeholder="輸入網址,如:http://www.baidu.com" value="http://s5ip.cn/3cjc">
</div>
</div>
<button type="button" class="btn btn-primary transfer">還原</button><span class="error" hidden></span>
</form>
<div class="row website-div" hidden>
<div class="col-md-2"></div>
<div class="col-md-1 website-name">原網址:</div>
<div class="col-md-9 website-value long-website"></div>
</div>
<div class="row website-div" hidden>
<div class="col-md-2"></div>
<div class="col-md-1 website-name">短網址:</div>
<div class="col-md-9 website-value short-website"></div>
</div>
</div>
</div>
<script src="https://cdn.bootcdn.net/npm/[email protected]/dist/jquery.min.js"></script>
<script>
$('.container .transfer').each(function(index, el) {
$(this).click(function(){
var website = $(this).siblings('.form-group').find('.website').val(),
_this = this,
find_val = index ? 'long-website' : 'short-website',
transfer_type = index;
if(website){
$(this).parent().siblings().find('.' + find_val).html('');
$.ajax({
url: 'website.php',
type: 'POST',
dataType: 'json',
data: {'website': website,'transfer_type': transfer_type},
success: function(msg){
if(msg.code == 0){
$(_this).parent().siblings('.website-div').show();
$(_this).parent().siblings('.website-div').find('.long-website').html(msg.data.old_website);
$(_this).parent().siblings('.website-div').find('.short-website').html(msg.data.new_website);
}else{
$(_this).siblings('.error').html(msg.msg).show();
}
}
})
}
})
});
</script>
</body>
</html>
s5ip.php代碼
<?php
$short_website = substr($_SERVER['QUERY_STRING'], 1);
if($short_website){
include_once "config.php";
$sql = 'SELECT long_website FROM web WHERE short_website = "'.$short_website.'"';
$resource = mysqli_query($conn,$sql);
$result = [];
while($row = mysqli_fetch_assoc($resource)){
$result = $row;
}
if($result){
$sql = 'UPDATE web SET times = times + 1 WHERE short_website = "'.$short_website.'"';
$resource = mysqli_query($conn,$sql);
header('Location:'.$result['long_website']);
}else{
exit('無效短網址');
}
}
config.php代碼
<?php
$conn = mysqli_connect('127.0.0.1','root','',"s5ip");
mysqli_query($conn,'set names utf8');
website.php代碼
<?php
header('content-type:text/html;charset=utf-8');
include_once "config.php";
include_once "function.php";
$url = trim($_POST['website']);
$transfer_type = trim($_POST['transfer_type']);
$host = $_SERVER['HTTP_ORIGIN'];
switch ($transfer_type) {
case '0'://縮短
if(is_valid_website($url)){
$sql = 'SELECT short_website FROM web WHERE long_website = "'.$url.'"';
$resource = mysqli_query($conn,$sql);
$result = [];
while($row = mysqli_fetch_assoc($resource)){
$result = $row;
}
if($result){
output('0','轉換成功',['old_website' => $url,'new_website' => $host.'/'.$result['short_website']]);
}else{
$short_website = round_str();
$sql = "INSERT INTO web(short_website,long_website) VALUES('$short_website','$url')";
$resource = mysqli_query($conn,$sql);
if($resource){
output('0','轉換成功',['old_website' => $url,'new_website' => $host.'/'.$short_website]);
}
}
}else{
output('-1','無效網址');
}
break;
case '1'://還原
$short_website = pathinfo($url)['filename'];
$sql = 'SELECT long_website FROM web WHERE short_website = "'.$short_website.'"';
$resource = mysqli_query($conn,$sql);
$result = [];
while($row = mysqli_fetch_assoc($resource)){
$result = $row;
}
if($result){
output('0','還原成功',['old_website' => $result['long_website'],'new_website' => $url]);
}else{
output('-1','無效短網址');
}
break;
}
function.php代碼
<?php
function is_valid_website($url){
$ch = curl_init();
$timeout = 10;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$contents = curl_exec($ch);
if(strpos($contents, '200 OK')){
return true;
}else{
return false;
}
}
function round_str($len = '4') {
$array_str = '';
$round_num = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ';
$round_num_arr = str_split($round_num);
$i = 0;
for ($i; $i < $len; $i++) {
$array_str .= $round_num_arr[mt_rand(1, strlen($round_num)-1)];
}
unset($round_num_arr);
return $array_str;
}
function output($code,$msg,$data = array()){
exit(json_encode([
'code' => $code,
'msg' => $msg,
'data' => $data
]));
}
資料表截圖
要先配置伺服器,才能通路,我用的是apache伺服器,開啟url重寫功能,在根目錄加上該檔案
.htaccess
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
現在通過浏覽器,位址欄輸入http://s5ip.cn/Do03 ,就可以通路http://www.baidu.com了
直接通路百度成功
我們再做進一步改造,做成對外的API接口
1、TXT格式短網址API接口
2、JSON格式短網址API接口
3、JSONP格式短網址API接口
api.php代碼
<?php
include_once "config.php";
include_once "function.php";
$url = $_GET['url'];
$format = isset($_GET['format']) ? trim($_GET['format']) : '';
$callback = isset($_GET['callback']) ? trim($_GET['callback']) : '';
$host = $_SERVER['REQUEST_SCHEME']."://".$_SERVER['SERVER_NAME'];
if(is_valid_website($url)){
$sql = 'SELECT short_website FROM web WHERE long_website = "'.$url.'"';
$resource = mysqli_query($conn,$sql);
$result = [];
while($row = mysqli_fetch_assoc($resource)){
$result = $row;
}
if($result){
$new_website = $host.'/'.$result['short_website'];
if(strtolower($format) == 'json'){
output('0','轉換成功',['old_website' => $url,'new_website' => $new_website]);
}elseif(strtolower($format) == 'jsonp'){
echo $callback."(".json_encode(['code' => '0','msg' => '轉換成功','new_website' => $new_website]).")";
}else{
echo $new_website;
}
}else{
$short_website = round_str();
$sql = "INSERT INTO web(short_website,long_website) VALUES('$short_website','$url')";
$resource = mysqli_query($conn,$sql);
if($resource){
output('0','轉換成功',['old_website' => $url,'new_website' => $host.'/'.$short_website]);
}
}
}else{
output('-1','無效網址');
}
接下來,我們寫個測試代碼,對短網址API進行調用
test.php
<?php
// $url = "http://s5ip.cn/api.php?url=".urlencode('http://www.baidu.com');
// $url = "http://s5ip.cn/api.php?format=json&url=".urlencode('http://www.baidu.com');
$url = "http://s5ip.cn/api.php?format=jsonp&callback=callbacknam&url=".urlencode('http://www.baidu.com');
echo curl($url);
function curl($url){
$ch = curl_init();
$timeout = 10;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$contents = curl_exec($ch);
if($contents){
return $contents;
}else{
return false;
}
}
此外,短網址還可以生成對應的二維碼。操作友善、快捷、高效!這部分内容,我們後續再寫……
不足之處,請多多指教。