ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 주소 줄이기(URL Shortener) (1)
    서버개발캠프 4기/스마게 ▶개발◀이야기 2020. 1. 10. 08:49

    사용 언어 : PHP, HTML

    사용 라이브러리 : mysql, bitnami

     

    [주소 축약]
    1. 주소를 입력받을 페이지를 만든다.
    2. 입력 받은 주소(Original URL, ourl)가 DB에 존재하는지 검색한다.
        2.1. 존재하지 않는다면 축약 과정(Short URL, surl)을 거쳐 DB에 저장한다.
    3. DB에서 ourl에 대응하는 surl을 출력한다.


    [축약 주소 Redirect]
    1. surl을 입력받는다.
    2. DB에 있는지 확인한다.
        2.1. 있다면 대응하는 ourl로 header 키워드를 이용해 redirect한다.
        2.2. 없다면 축약하는 사이트로 redirect한다.

     

    [주소 축약]

    1. 주소를 입력받을 페이지를 만든다. 

    정말 적당하게 만든 페이지. 물론 최종 제출하기 전에는 조금 더 꾸미려고 노력하긴 했다. 마음대로 안됐을 뿐...

    사실 '페이지를 만든다'라고 거창하게 말했지만 html을 한 번도 안다뤄본 나로써는

    페이지 만드는 것도 힘들었다.

    그래서 그냥 입력 폼과 확인 버튼만 넣었다.

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>URL Shortening</title>
    </head>
    <body>
        <form action="db.php" method="POST">
            <input type="text" name="ourl" placeholder="URL to Shorten">
        <button type="submit">Submit</button>
        </form>
    </body>
    </html>

     

    2. 입력 받은 주소(ourl)가 DB에 존재하는지 검색하고 없다면 주소를 축약해 삽입한다.

     

    <?php
    $ourl = $_POST['ourl'];
    
    if(checkOverlap($ourl) == false)
    {
        insertNewData($ourl);
    }
    
    echo showShortenURL($ourl)
    ?>

    구조를 한글로 적어보자면 이렇다.

    if (중복 == false)
    {
       주소 축약
       새로운 데이타 삽입
    }

    축약된 주소 표시

     

    중복 체크

    <?php
    function checkOverlap($url)
    {
        $conn = mysqli_connect('localhost', '이름', '비번', 'urlshortening');
        $sql = "SELECT * FROM topic WHERE ourl = '$url'";
        $result = mysqli_query($conn, $sql);
        if($result->num_rows == 0)
            return false;
        return true;
    }
    ?>

    파라미터로 url을 받으면 DB로 접근해서 $result를 받아온다.

    그 후 $result의 길이가 0이면 즉, 아무것도 없다면

    중복되는 데이터가 없으므로 false를 return한다.

    $result의 길이가 0이 아니라면 해당 url이 이미 존재하는 것이므로

    true를 return한다.

     

    새로운 데이터를 DB에 삽입

    <?php
    function insertNewData($url)
    {
        $conn = mysqli_connect('localhost', '이름', '비번', 'urlshortening');
        $surl = shorting($url);
        $sql="
        INSERT INTO topic
            (ourl, surl)
            VALUES
            ('$url', '$surl')
        ";
        $result = mysqli_query($conn, $sql);
        if($result == false)
        {
            echo 'Sth error on saving.';
        }
        else
        {
            echo 'Successfully Shortened. <br>';
        }
    }
    ?>

    함수 두번째 줄의 $surl은 파라미터로 입력받은 url을 줄인녀석이다.

    shorting이라는 함수를 이용해 주소를 축약한다. (shorting 함수는 뒤에 서술)

    이후 sql문을 이용해 DB에 저장한다.

     

    주소 축약

    <?php
    function shorting($url)
    {
        $conn = mysqli_connect('localhost', '이름', '비번', 'urlshortening');
        $sql = "SELECT * FROM topic ORDER BY id DESC LIMIT 1";
        $result = mysqli_query($conn, $sql);
        if($result->num_rows == 0)
            return '000000';
        
        $surl = ($result->fetch_object()->id) + 1;
        return encoding($surl);
    }
    
    function encoding($id)
    {
        $leftStrCnt = 6 - strlen($id);
        $leftStr = '';
        for($i=0; $i<$leftStrCnt; $i++)
        {
            $leftStr = $leftStr.'0';
        }
    
        return $leftStr.$id;
    }
    ?>

    축약은 주소 자체를 축약하는 것이 아니라

    Auto_Increment 설정된 id를 축약하는 것으로 했다.

    하지만 아직 저장되지 않은 데이터의 id를 가지고 오는 방법을 잘 몰랐기 때문에

    table을 id의 역순으로 정렬하고 Limit 1을 걸어서

    첫번째, 즉 역순이니까 id가 제일 큰 행을 가져와서

    그 행의 id 값에 1을 더한 값을 encoding하는 방법을 사용했다.

     

    만약 테이블이 비어있다면 사용할 수 없는 방법이기에
    num_rows가 0이라면 그냥 '000000'을 return하도록 했다.

     

    사실 축약(encoding)은 야매로 했다.

    들어보니 실제로는 base62를 사용해 축약한다고 했지만

    연습/경험용이기 때문에 그냥 id를 그대로 사용하는 10진법으로 했다.

    다만 개인 과제 요구사항 중에 축약된 주소는 항상 동일한 자리수여야 한다는 조건이 있어서

    encoding이라는 함수를 사용해 자리수를 맞췄다.

     

    encoding함수는 별거 아니다.
    나는 6자리로 맞추고 싶어서 현재 id의 길이를 파악한 다음
    부족한 만큼 앞에 '0'을 추가했다.

     

    해당하는 데이터 출력

    <?php
    function showShortenURL($url)
    {
        $conn = mysqli_connect('localhost', '이름', '비번', 'urlshortening');
        $sql = "SELECT surl FROM topic WHERE ourl='$url'";
        $result = mysqli_query($conn, $sql);
    
        $surl = $result->fetch_object()->surl;
    
        return "Your shorten URL is <a href='https://$url'>localhost/$surl</a>";
    }
    ?>

    DB에 ourl이 있음이 보장됐기 때문에

    이후는 그냥 찾아서 보여주기만 하면 된다.

    id를 가져올 때와 같은 방법으로 surl을 가져와서

    화면에 띄워준다.

     

    결과

    축약 성공 시 표시되는 페이지

    <!doctype html>
    <html lang="en">
      <head>
        <title>URL Shortening</title>
    </head>
    <body>
    <?php
      $ourl = $_POST['ourl'];
    
      if(checkOverlap($ourl) == false)
      {
          insertNewData($ourl);
      }
      echo showShortenURL($ourl);
    ?>
    <body>
    </html>

     

    글이 너무 길어져서 리다이렉트 관련해서는 다음 글로 넘겨야겠다.

Designed by Tistory.