天天看點

關于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;
        }
    }
           

此外,短網址還可以生成對應的二維碼。操作友善、快捷、高效!這部分内容,我們後續再寫……

不足之處,請多多指教。