天天看点

关于php短网址服务的实战案例

说到短网址,那什么是短网址呢?

短网址(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>
           
关于php短网址服务的实战案例
关于php短网址服务的实战案例

 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
        ]));
    }
           

数据表截图

关于php短网址服务的实战案例

要先配置服务器,才能访问,我用的是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了

关于php短网址服务的实战案例

直接访问百度成功

关于php短网址服务的实战案例

我们再做进一步改造,做成对外的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;
        }
    }
           

此外,短网址还可以生成对应的二维码。操作方便、快捷、高效!这部分内容,我们后续再写……

不足之处,请多多指教。