说到短网址,那什么是短网址呢?
短网址(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 lang="en"> <head> <meta charset="UTF-8" /> <link href="https://cdn.bootcdn.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" 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/jquery@1.12.4/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/jquery@1.12.4/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; } }此外,短网址还可以生成对应的二维码。操作方便、快捷、高效!这部分内容,我们后续再写……
不足之处,请多多指教。