کوتاه کننده لینک با PHP و MYSQL

4 سال پیش - خواندن 9 دقیقه

کوتاه کننده لینک با PHP و MYSQL

کوتاه کننده لینک با PHP ، مای اس کیو ال و Javascript – ساخت یک انتقال دهنده لینک نیازمند این است که راه حلی را داشته باشیم که بتوانیم یک آدرس طولانی را به یک آدرس کوتاه تبدیل کنیم .


در این آموزش یک URL Shortener نیمه حرفه ای را خواهیم ساخت که از تکنولوژی Ajax پشتیبانی می کند . 


فایل index.php

خط 18 : از اونجایی که فرم ajax خواهد بود زمانی که آدرس وارد شد و کاربر ENTER زد نمی خواهیم هدایت بشیم بنابراین با onSubmit مقدار false برمی گردانیم کــــه ریدایرکت نشیم .
خط 19 : pattern را برای ورودی http و https تنظیم می کنیم که با یکی از این 2 شروع شود .

<?php
require_once "functions.php";
require_once "func.actions.php";
if(!empty($_GET['u']))require_once "redirect.php";
?>
<!DOCTYPE html>
<html lang="fa">
<head>
    <meta charset="UTF-8">
    <title>Rapidcode.iR - سورس کد</title>
    <link rel="stylesheet" href="static/css/main.css">
</head>
 
<body>
    <div class="container">
        <a id="introduce" href="https://rapidcode.ir" target="_blank">رپید کد • کتابخانه مجازی برنامه نویسان</a>
 
        <form onSubmit="return false;">
            <input autofocus pattern="https:\/\/.*|http:\/\/.*" type="url" name="url-inp" id="url-inp"
                placeholder="لینک مورد نظر برای کوتاه شدن"><br><br>
            <input type="button" id="submit" value="کوتاه کن">
        </form>
 
        <?php if(isset($GLOBALS['is_url_correct']) && !$GLOBALS['is_url_correct']) echo generate_html_message("آدرس مورد نظر در پایگاه داده یافت نشد ." , "warning") ?>
        <?php if(!empty($GLOBALS['info_msg'])) echo $GLOBALS['info_msg'] ?>
 
        <div class="short-link-wrapper">
            <button id="copy-short-link" data-clipboard-target="#short-link-copy">
                <img src="static/img/clippy.svg" alt="copy text">
            </button>
            <input id="short-link-copy" type="url" readonly placeholder="short link goes here (;" dir="ltr">
        </div>
    </div>
 
    <script src=static/js/lib/clipboard.min.js> </script>
    <script src="static/js/app.js"></script>
</body>
</html>


فایل contants.php برای اطلاعات ثابت مثل دیتابیس

<?php
 
define("HOST" , "localhost");
define("USERNAME" , "root");
define("PASSWORD" , "");
define("DB" , "link_db");
define("CURRENT_TIME" , date("Y/m/d H:i:s"));
 
?>


فایل functions.php برای تابع های دیتابیس

<?php
 
require_once "constants.php";
$table = "link_tbl";
 
function validate_url(string $url)
{   
    $url_list = parse_url($url);
    $host = $url_list['host'];
    $path = $url_list['path'];
    $url = str_ireplace($path , urlencode($path) , $url);
    $url = str_ireplace($host . "%2f" , $host . "/" , $url);
    $url = filter_var($url, FILTER_VALIDATE_URL);
    return $url;
}
 
function show_json_message($array_data)
{
    return json_encode($array_data);
}
 
function generate_url_token($url)
{
    $crc32_number = crc32($url);
    $encoded_url = base_convert($crc32_number, 10, 36);
    $encoded_url_list = str_split($encoded_url, 1);
    $encoded_url = "";
 
    for ($i = 0; $i < sizeof($encoded_url_list); $i++) {
        $current_index = $encoded_url_list[$i];
        $letter = is_numeric($current_index) ? $current_index : strtoupper($current_index);
        $encoded_url .= $letter;
    }
 
    return $encoded_url;
}
 
function generate_html_message($message = "", $type = "notice")
{
    return "<div class=\"msg {$type}\"><p>{$message}</p></div>";
}
 
function remove_end_slash($url)
{
    $url = strrev($url);
    $url = str_split($url, 1);
 
    if ($url[0] == "/") unset($url[0]);
 
    $url = join($url);
    $url = strrev($url);
 
    return $url;
}
 
function update_views($column, $short_url)
{
 
    $mysqli = new mysqli(HOST, USERNAME, PASSWORD, DB);
    $current_time = CURRENT_TIME;
    $row_updated = 0;
 
    $mysqli->set_charset("utf8");
    $stmt = $mysqli->stmt_init();
    $query = "UPDATE `{$GLOBALS['table']}` SET `views` = views + 1 , `date_last_view` = ? WHERE {$column} = ?";
 
    $stmt->prepare($query);
    $stmt->bind_param('ss', $current_time, $short_url);
 
    if ($stmt->execute()) {
        $row_updated = $stmt->affected_rows ? $stmt->insert_id : 0;
    }
 
    $stmt->close();
    $mysqli->close();
 
    return $row_updated;
}
 
function row_select($user_query, $column, $select = "*")
{
 
    $mysqli = new mysqli(HOST, USERNAME, PASSWORD, DB);
    $row = 0;
 
    $mysqli->set_charset("utf8");
    $stmt = $mysqli->stmt_init();
    $query = "SELECT {$select} FROM `{$GLOBALS['table']}` WHERE {$column}=?";
 
    $stmt->prepare($query);
    $stmt->bind_param("s", $user_query);
 
    if ($stmt->execute() && $res = $stmt->get_result()) {
        if ($stmt->affected_rows || $res->num_rows) {
            $row = $res->fetch_assoc();
        }
    }
 
    $stmt->close();
    $mysqli->close();
 
    return $row;
}
 
function row_insert($url)
{
    $mysqli = new mysqli(HOST, USERNAME, PASSWORD, DB);
    $views = 0;
    $token_url = generate_url_token($url);
    $inserted_id = 0;
    $current_time = CURRENT_TIME;
 
    $mysqli->set_charset("utf8");
    $stmt = $mysqli->stmt_init();
 
    $query = "INSERT INTO `{$GLOBALS['table']}` (link_original , link_short , date_submitted , date_last_view , views) VALUES (? , ? , ? , ? , ?)";
 
    $stmt->prepare($query);
    $stmt->bind_param('ssssi', $url, $token_url, $current_time, $current_time, $views);
 
    if ($stmt->execute()) {
        $inserted_id = $stmt->affected_rows ? $stmt->insert_id : 0;
    }
 
    $stmt->close();
    $mysqli->close();
 
    return $inserted_id;
}


فایل func.actions.php 

این فایل شامل 3 تابع است که 3 عمل اصلی را هم انجام می دهد :

  1. فانشکن func_action_submit : برای زمانی که لینکی را ثبت می کنیم .
  2. فانشکن func_action_redirect : کاربر را با لینک کوتاه به لینک اصلی هدایت می کند .
  3. فانشکن func_action_redirect_info : اطلاعاتی از لینک کوتاه ثبت شده به ما می دهد شامل تاریخ ثبت لینک ، تاریخ آخرین ارجاع یا بازدید از لینک ، تعداد بازدید .
<?php
 
function func_action_submit($response_list, $user_url)
{
     $row = row_select($user_url, "link_original");
     if (empty($row)) {
          $row = row_insert($user_url);
          if (empty($row)) {
               $response_list['status'] = 0;
               $response_list['msg'] = "خطایی در هنگام ثبت داده در دیتابیس رخ داده .";
               die(show_json_message($response_list));
          } else {
               $response_list['status'] = 1;
               $response_list['msg'] = "آدرس مورد نظر با موفقیت ثبت گردید .";
               $response_list['data'] = json_encode(row_select($row, "id", "link_short"));
               die(show_json_message($response_list));
          }
     } else {
          $response_list['msg'] = "این آدرس از قبل ثبت شده";
          $response_list['data'] = json_encode(["link_short" => $row['link_short']]);
          die(show_json_message($response_list));
     }
}
 
function func_action_redirect($user_url)
{
     $url_data = row_select($user_url, "link_short", "link_original");
     $GLOBALS['is_url_correct'] = false;
     if (!empty($url_data)) {
          update_views("link_short", $user_url);
 
          header("Location: {$url_data['link_original']}");
          $GLOBALS['is_url_correct'] = true;
     }
}
 
function func_action_redirect_info($user_url)
{
     $url_data = row_select($user_url, "link_short", "*");
     $url_data['link_original'] = urldecode($url_data['link_original']);
     $GLOBALS['is_url_correct'] = false;
     if (!empty($url_data)) {
          $GLOBALS['info_msg'] = "<div style=\"direction: ltr;font-size:25px\" class=\"msg success\"><p>{$url_data['link_original']}</p></div><table id=\"statistics\"><tr><td>تاریخ ثبت لینک : </td><td>{$url_data['date_submitted']}</td></tr><tr><td>تاریخ آخرین ارجاع لینک : </td><td>{$url_data['date_last_view']}</td></tr><tr><td>تعداد ارجاع : </td><td>{$url_data['views']}</td></tr></table>";
          $GLOBALS['is_url_correct'] = true;
     }
}


فایل redirect.php 

این تابع مشخص می کند که کاربر با لینک کوتاهی که وارد کرده است می خواهد به لینک اصلی وارد شود یا آمار لینک را مشاهده کند .

<?php
 
if($_GET['u'] && !empty($_GET['info'])){
    func_action_redirect_info($_GET['u']);
}else if($_GET['u']){
    func_action_redirect($_GET['u']);
}
 
?>


فایل api.php 

از اسمی که دارد برای endpoint استفاده می شود که درخواست های ajax به این فایل ختم می شود . 

<?php
 
header("Content-Type: application/json");
require_once "functions.php";
require_once "func.actions.php";
 
$response_list = [
    "status" => 0,
    "msg" => "",
    "data" => []
];
 
$action_list = [
    "submit",
];
 
$user_url = @$_POST['inp-url'];
$action = @$_POST['action'];
 
if(empty($action) || !in_array($action , $action_list)){
    $response_list['msg'] = "پارامتر action معتبر نمی باشد .";
    die(show_json_message($response_list));
}
 
$user_url = remove_end_slash($user_url);
 
if(empty($user_url) || !validate_url($user_url)){
    $response_list['msg'] = "لینک معتبری وارد نشده است .";
    die(show_json_message($response_list));
}
 
$user_url = urldecode($user_url);
call_user_func("func_action_" . $action , $response_list , $user_url);
 
?>


فایل app.js 

const clipboardJS = new ClipboardJS('#copy-short-link');
 
const submitDOM = document.getElementById("submit");
const urlInput = document.getElementById("url-inp");
const shortLinkWrapper = document.getElementsByClassName("short-link-wrapper")[0];
 
 
submitDOM.addEventListener("click", handlerSubmit);
 
 
function handlerSubmit() {
    if (!urlInput.checkValidity()) {
        alert("آدرس داده شده معتبر نمی باشد .");
        return false;
    }
 
    submitDOM.setAttribute("disabled", "disabled");
    submitDOM.value = "در حال دریافت لینک ...";
 
    funcPostRequest(function (xhr) {
        const response = xhr.currentTarget.response;
        let data = response.data;
 
        if(typeof data == "string") data = JSON.parse(data);
 
         
        window.alert(response.msg);
        if (data['link_short']) {
            shortLinkWrapper.classList.add("active");
            submitDOM.removeAttribute("disabled");
            submitDOM.value = "کوتاه کن";
            shortLinkWrapper.querySelector("#short-link-copy").value = location.origin + "?u="+ data['link_short'];
        }
 
 
 
    }, function () {
        alert("خطایی رخ داده برای جزئیات بیشتر تب console را باز کنید")
        console.warn("[XHR Error]");
 
        submitDOM.removeAttribute("disabled");
        submitDOM.value = "کوتاه کن";
    });
 
}
 
 
function funcPostRequest(cbOnload, cbOnerror) {
    const xhr = new XMLHttpRequest();
    xhr.responseType = "json";
 
    const params = new FormData;
    params.append("action", "submit");
    params.append("inp-url", urlInput.value);
 
    xhr.open("POST", location.origin + "/api.php");
 
    xhr.onload = cbOnload;
    xhr.onerror = cbOnerror;
 
    xhr.send(params);
}


فایل main.css 

body{
    background-image: url(../img/sea.jpg);
    background-size: cover;
}
 
.active{
    display: block !important;
}
 
#url-inp{
    transition: 0.3s all;
    width: 40%;
    border: none;
    outline: none;
    padding: 10px;
    border-radius: 25px;
    text-align: center;
    font-weight: bold;
}
 
#url-inp:focus{
    width: 50%;
    border: 1px solid #000;
}
 
#submit{
    border: none;
    background-color: #2196f3;
    color: white;
    font-weight: bold;
    font-size: 25px;
    padding: 10px 50px;
    border-radius: 25px;
    cursor: pointer;
}
 
#submit:hover{
    background-color: #137dd3;
}
 
.msg{
    background-color: silver;
    color: #000;
    border-radius: 15px;
    display: inline-block;
    padding: 5px 35px;
    margin: 15px auto;
    font-weight: bold;
}
 
.msg.warning{
    background-color: #ffa500;
}
 
.msg.success{
    background-color: #3f51b5;
    color: white;
}
 
#statistics{
    font-weight: bold;
    background-color: rgb(255 255 255 / 79%);
    border-radius: 4px;
    width: 50%;
    margin: 0 25%;
}
 
#statistics td{
    padding: 12px;
}
 
.short-link-wrapper{
    display: none;
}
 
#short-link-copy{
    margin-top: 50px;
    font-size: 24px;
    background-color: #4caf50;
    border: 3px #fff solid;
    outline: none;
    color: white;
    padding: 3px 10px;
    border-radius: 15px;
}
 
.short-link-wrapper button{
    height: 25px;
}
 
.short-link-wrapper button img{
    width: 15px;
}


دموی برنامه

https://rapidcode.ir/wp-content/uploads/2021/10/tga-1634371759-cmp.mp4


برای دانلود پروژه به لینک زیر مراجعه کنید

لینک دانلود برنامه کوتاه کننده لینک

https://yun.ir/iqaqdc

1
کــارمـا :
44
یک برنامه نویس خوشحال 0o0
بفرست

مشاهده نظرات بیشتر...
seniorx