Förkorta länkar utan skräp (F3)

Förkorta länkar utan skräp (F3)

Att förkorta länkar i 13 år är inte pinsamt, eller hur? En nybörjare, och inte bara nybörjare, borde prova att skriva sin egen Länkkrigare, medan de lär sig ett nytt ramverk. Det är precis vad jag har sysslat med. Vad kan man säga — femte versionen av Bootstrap, ett lätt ramverk och en del av själen.

Här är demoversioner, och här är kod. För läsare som jag 😉

Ramverk, eller hur?

Självklart inte Laravel och liknande — idag klarar vi oss med 65 kilobyte. FatFreeFramework. Om du är bekant med Python Flask, kommer du att få känslan av att detta har gjorts förut:

#роутинг во Фласке
@app.route('/')
def hello_world():
    return 'Hello, World!'
//роутинг в Обезжиренном
$f3->route('GET /',
    function() {
        echo 'Hello, world!';
    }
);

Okej, glöm det. Ladda ner .zip från den officiella hemsidan, packa upp i mappen som just nu öppnas i din Favorit Kodredigerare. Rensa index.php och ta bort allt från /ui.

Här är allt ganska enkelt — i mappen ui har vi alla vyer, eller enklare uttryckt — förfinade HTML-mallar som vi kommer att visa användaren när de går in på en viss URL.

Här är stommarna för vår "applikation":

set('DEBUG', 1);
if ((float)PCRE_VERSIONconfig('config.ini');

// ALL ÖVRIG KOD SKRIVS HÄR

$f3->run();

Och det är allt du behöver veta för att komma igång. Låt oss börja koda!

[För utvecklingen använde jag en lokal XAMPP på Windows och VS Code, artikeln skriven i Notion]

Hem

Vi börjar med startsidan. Logiskt, eller hur?

//Файл: index.php

$f3->route('GET /',
    function($f3) { //чтобы использовать функции F3 передаем его в роут
                $view = new View; // создаем вьюшку
        echo $view->render('home.htm'); //рендерим шаблон
    }
);

Nu behöver vi skriva själva mallen. För enkelhetens skull använde jag Bootstrap v5 alpha.

Glöm inte att skapa alla mallar i mappen ui, annars är de inte att inte synliga för ramverket

<!-- Файл: ui/home.htm -->

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="<?php echo $ENCODING; ?>" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Vi skriver (kod), förkortar (länkar)!</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
    </head>
    <body class="text-center bg-dark text-light"> <!-- темная тема ;) -->

        <!-- менюшка -->
        <nav class="m-2">
            <ul class="nav nav-pills justify-content-center">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">Hem</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Artikel på Habré</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Skapare</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Kortlänkare är här.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/sv/newLink/" method="POST" data-trp-original-action="/newLink/">
            <div class="row justify-content-center">
                <div class="col-auto">
                <label for="inputLink" class="col-form-label">Ange länk:</label>
                </div>
                <div class="col-auto">
                <input required placeholder="https://" type="url" name="link" id="inputLink" class="form-control mb-1" aria-describedby="inputLink">
                </div>
                <div class="col-auto">
                <button type="submit" class="btn btn-outline-primary">Förkorta!</button>
                </div>
            </div>
        <input type="hidden" name="trp-form-language" value="sv"/></form>

        <!-- немного -->
        <p class="text-left m-auto mb-5" style="max-width: 30rem;">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Omnis illum molestiae hic fugiat molestias nemo, architecto beatae repellat ullam exercitationem non ab, necessitatibus maxime quod iure ipsa quam quos! Reprehenderit. Lorem ipsum dolor, sit amet consectetur adipisicing elit. Necessitatibus eos sapiente voluptates veniam sequi delectus totam tenetur praesentium obcaecati. Repudiandae quisquam, ipsa ullam corrupti molestiae minima optio nihil est modi?</p>

        <footer class="m-2">Gjort med <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="med kärlek">, <a href="https://v5.getbootstrap.com/">femte Bootstrap</a>    och <a href="https://fatfreeframework.com/">utan fett</a></footer>
        </div>
    </body>
</html>

Och så är det klart, vi har redan en fungerande startsida. Formuläret skickar en POST-förfrågan med länken som ska förkortas.
Nu kommer det intressanta (eller inte).

Arbete med databasen

Vi skapar en databas — MySQL. Om du har installerat PhpMyAdmin, skapa en ny databas "linker", och kör sedan denna SQL:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

CREATE TABLE IF NOT EXISTS `links` (
  `code` varchar(4) NOT NULL,
  `link` varchar(1000) NOT NULL,
  `hits` int(255) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `links`
  ADD UNIQUE KEY `code` (`code`);

Vi kommer att ha 3 fält för varje länk:

  1. Code — det är fyra slumpmässiga tecken efter domänen som kommer att användas för omdirigering, exempelvis example.com/ABC1
  2. Link — Den förkortade länken.
  3. Hits — antalet klick på den förkortade länken.

Jag ska kort förklara hur man arbetar med databasen, utan krusiduller.

set('result', $db->exec('SELECT * FROM wherever')); 
//de kommer att vara tillgängliga i mallar som 

//Eller så kan man använda den inbyggda SQL Mapper:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); //nu är alla kolumner i raden där länken till Habra tillgängliga:
$row_value = $row->somerow; //Så här

//Självklart kan man ändra värden:
$row->link = 'https://habr.com';
$row->save(); //ändringarna måste sparas, vad trodde du

//mer information om att arbeta med databasen finns här: https://a.nikonovs.ru/MPHR Jag rekommenderar verkligen att läsa, åtminstone med hjälp av översättaren som finns i webbläsaren.
?>

Vi börjar med att förkorta.

Bearbetar ny länk

Skapar en ny vy i index’e, som kommer att bearbeta förfrågan från formuläret på startsidan.

Först skapar vi en ny, men mycket lik den första (home.htm) mall — "newLink.htm".
Där kommer vi att visa den förkortade länken och antalet klick på den (för att återse denna "statistik" måste vi förkorta samma länk igen — adressen förblir densamma).
För att visa, använder vi en trick med "övergång av variabler":

set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
//Nu kan vi använda i mallen:

Och här är koden newLink.html:

<!-- Файл: newLink.htm -->

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="<?php echo $ENCODING; ?>" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Vi skriver (kod), förkortar (länkar)!</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
    </head>
    <body class="text-center bg-dark text-light">
        <nav class="m-2">
            <ul class="nav nav-pills justify-content-center">
                <li class="nav-item">
                    <a class="nav-link" aria-current="page" href="/sv/">Hem</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Artikel på Habré</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Skapare</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Kortlänkare är här.</h1>

        <!-- Убираем из формы функционал формы и выводим переменные -->
        <form class="mt-5 mb-3" action="">
            <div class="row justify-content-center">
                <div class="col-auto">
                    <label for="inputLink" class="col-form-label">Kortat:</label>
                </div>
                <div class="col-auto">
                    <input disabled required type="url" name="link" id="inputLink" class="form-control disabled" aria-describedby="inputLink" value="<?= $link ?>">
                </div>
            </div>
            <p class="m-2 text-secondary">Gå till denna länk: ``</p>
        <input type="hidden" name="trp-form-language" value="sv"/></form>

        <a href="/sv/" class="mt-3 mb-5 btn btn-primary btn-lg">ÅTERVÄNDA TILL HUVUDSIDAN</a>

        <footer class="m-2">Gjort med <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="med kärlek">, <a href="https://v5.getbootstrap.com/">femte Bootstrap</a>    och <a href="https://fatfreeframework.com/">utan fett</a></footer>
        </div>
    </body>
</html>

Vi skriver själva routen.

$f3->route('GET|POST /newLink', ////vi kommer att behandla både POST och GET
    function($f3) {

            $db = new DBSQL( ////Anslutning till databasen, ny vid varje rutt
                'mysql:host=localhost;port=3306;dbname=linker',
                'root',
                ''
            );

            ////utmärkt funktion för att generera slumpmässiga tecken:
            $permitted_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            function generate_string($input, $strength = 4) {
                $input_length = strlen($input);
                $random_string = '';
                for($i = 0; $i load(array('link="'. $link .'"'));
            if ($check->dry()) {
                $g_code = generate_string($permitted_chars);
                $row = new DBSQLMapper($db,'links');
                $row->reset();
                $row->code = $g_code;
                $row->link = $link;
                $row->save();
            } else {
                $g_code = $check->code; ////om länken upprepas, visa den gamla koden
            }

            $short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; ////sammanställ den slutliga länken

            ////parametrar från $_POST kan fås med $f3->get('POST'), punktnotation stöds (korrigera mig om jag kallar det fel): parametrar "link" kan fås så här: 
            $link = $f3->get('POST.link');

            if ( !empty($f3->get('POST')) ) { ////Vi visar HTML endast om POST inte är tomt.

            $f3->set('link', $short_link);
            $f3->set('hits', $check->hits);
            $view = new View;
            echo $view->render('newLink.htm');

            } else { ////annars - omdirigera till startsidan
                $f3->$f3->reroute('/');
            }

        }
);

Färdigt! Det var faktiskt enkelt.

Omdirigering

Det som återstår är:

  1. Hämta parametrar från URL
  2. Kontrollera om den finns i databasen
  3. Hämta motsvarande länk från databasen
  4. Omdirigera användaren
  5. Vinst!

Vi fortsätter att skriva kod efter den föregående rutten.

$f3->route('GET /@code', //anger a parameter after "@", it will fall into PARAMS
    function($f3) {

        //again define $db
        $db = new DBSQL(
            'mysql:host=localhost;port=3306;dbname=linker',
            'root',
            ''
        );

        $code = $f3->get('PARAMS.code'); //get the parameter

        $link = new DBSQLMapper($db,'links'); 

        //if we can get the link from the database - we get it, increase the number of transitions, and redirect
        if ($link->load(array('code="' . $code . '"', 'link=?'))) {
            $link->hits++;
            $link->save();

            $f3->reroute($link->link);
        } else {
            $f3->reroute('/'); //if there is no such link - welcome to the main page
        }
    }
);

Du kanske har lagt märke till att i och i routen newLink, och i routen ovan definieras samma sak — för code kan överensstämma med "newLink" (kan inte, i generatorn endast stora bokstäver), men eftersom den definieras först så kommer den att köras först.

$f3→run()!

Tack för att du läste!
Jag skulle uppskatta om du skrev en kommentar och rättade om något är fel.

Och som hemläxa eller bevis på min lathet, lämnar jag en lista på vad man kan göra. Att lära sig genom praktik är bäst!

  • Det är självklart osannolikt, men vid generering $g_code kan upprepas, så jag föreslår att du skriver en funktion som kontrollerar detta.
  • Man kan också skapa statistik och visa den vid övergång till /@code/stats
  • Förbjud att skapa länkar till själva tjänsten för att förkorta länkar, skapa en lista över "skyddade" resurser från förkortning
  • Jag rekommenderar starkt att även i ett litet projekt göra validering av inmatning på serversidan, med rätta felmeddelanden, man ska inte bara förlita sig på att lägga till attributet required och typen type="url" på inmatningsfältet
    RedComrade

  • Skriv gärna förslag i kommentaren…

    Vi hörs)

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster