说到短网址,那什么是短网址呢?
短网址(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;
}
}
此外,短网址还可以生成对应的二维码。操作方便、快捷、高效!这部分内容,我们后续再写……
不足之处,请多多指教。