Forkorter links uden fyld (F3)

Forkorter links uden fyld (F3)

At 13 years old, shortening links isn't something to be ashamed of, right? A beginner, and not just a beginner, should try writing their own Link Tamer while learning some new framework. That's what I set out to do. What can I say — the fifth Bootstrap, a lightweight framework, and a piece of my soul.

Her er demo, men her er koden. For readers like me 😉

A framework, right?

Definitely not Laravel and similar ones — today we'll manage with 65 kilobytes FatFreeFramework. If you are familiar with Python Flask, you'll feel like this has been done before:

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

Okay, forget it. Let's download .zip from the official site, unzip it into a folder that opens in your Favorite Code Editor right away. Clear index.php and remove everything from /ui.

It's all quite simple — in the folder ui we have all the Views, or in simpler terms — enhanced HTML templates that we will show to the user when accessing a specific URL.

Here's the skeleton of our "application":

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

// ALL OTHER CODE WILL BE WRITTEN HERE

$f3->run();

That's all you need to know to get started. Let's get coding!

[for development I used local XAMPP on Windows and VS Code, the article was written in Notion]

Homepage

Let's start with the homepage. Makes sense, doesn't it?

//Файл: index.php

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

Now we need to write that very template. To keep it simple, I used Bootstrap v5 alpha.

Don't forget to create all templates in the folder ui, otherwise they vises som tomme. I stedet vil der blive vist en fejlmeddelelse, så brugeren bedre kan forstå, hvad der skete. are not visible to the framework

<!-- Файл: 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 (kode), forkorter (links)!</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="#">Forside</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">Skaber</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Korte links er allerede her.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/da/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">Indtast link:</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">Forkorte!</button>
                </div>
            </div>
        <input type="hidden" name="trp-form-language" value="da"/></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">Lavet med <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="kærlighed">, <a href="https://v5.getbootstrap.com/">femte Bootstrap</a>    og <a href="https://fatfreeframework.com/">uden fedt</a></footer>
        </div>
    </body>
</html>

And that's it, we already have a working homepage. The form sends a POST request with the link that needs to be shortened.
Now for the interesting part (not really).

Arbejdet med databasen

Let's create a database - MySQL. If you have PhpMyAdmin installed, create a new database called "linker", then run this 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`);

Each link will have 3 fields:

  1. Code — random 4 characters after the domain, which will be used for redirection, like example.com/ABC1
  2. Link — The unshortened link.
  3. Hits — the number of clicks on the shortened link.

I'll briefly explain how to work with the database, without any fluff.

set('result', $db->exec('SELECT * FROM wherever')); 
// De vil være tilgængelige i skabeloner som 

// Eller man kan bruge den indbyggede SQL Mapper:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); // Nu er alle kolonner i rækken tilgængelige, hvor linket er til Habr:
$row_value = $row->somerow; // Sådan

// Selvfølgelig kan man ændre værdierne:
$row->link = 'https://habr.com';
$row->save(); // Ændringerne skal gemmes, hvad tænkte du?

// Mere information om at arbejde med databaser kan findes her: https://a.nikonovs.ru/MPHR Jeg anbefaler stærkt at læse det, selvom det er med hjælp fra oversætteren i browseren.
?>

Lad os begynde at forkorte.

Behandling af et nyt link

Vi opretter en ny visning i index'en, der vil behandle forespørgslen fra formularen på forsiden.

Først opretter vi en ny, men meget lignende skabelon til den første (home.htm) — "newLink.htm".
" Her vil vi vise det forkortede link og antallet af klik på det (for at se denne "statistik" igen, skal linket forkortes igen — adressen forbliver den samme).
For at vise dette bruger vi en trick med "overførsel af variable":

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

Her er opstillingen 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 (kode), forkorter (links)!</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="/da/">Forside</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">Skaber</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Korte links er allerede her.</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">Reduceret:</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">Klik på dette link: ``</p>
        <input type="hidden" name="trp-form-language" value="da"/></form>

        <a href="/da/" class="mt-3 mb-5 btn btn-primary btn-lg">TILBAGE TIL HJEMMESIDEN</a>

        <footer class="m-2">Lavet med <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="kærlighed">, <a href="https://v5.getbootstrap.com/">femte Bootstrap</a>    og <a href="https://fatfreeframework.com/">uden fedt</a></footer>
        </div>
    </body>
</html>

Vi skriver selve ruten.

$f3->route('GET|POST /newLink', // Vi behandler både POST og GET
    function($f3) {

            $db = new DBSQL( // Oprettelse af en ny DB-forbindelse i hver rute
                'mysql:host=localhost;port=3306;dbname=linker',
                'root',
                ''
            );

            // Fantastisk funktion til at generere tilfældige tegn:
            $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; // hvis link er duplikeret, så vises den gamle kode
            }

            $short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; // samler den endelige link

            // Parametre fra $_POST kan hentes med $f3->get('POST'), understøtter punktnotations (ret mig, hvis jeg kalder det forkert): parameter "link" kan hentes på denne måde: 
            $link = $f3->get('POST.link');

            if ( !empty($f3->get('POST')) ) { // Vi udsteder HTML, kun hvis POST ikke er tom.

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

            } else { // ellers - omdirigér til hovedsiden
                $f3->$f3->reroute('/');
            }

        }
);

Færdig! Faktisk var det ret nemt.

Omdirigering

Der er kun én ting tilbage:

  1. Hent parameter fra URL
  2. Tjek dens tilstedeværelse i databasen
  3. Hent det relevante link fra databasen
  4. Omdirigér brugeren
  5. Profit!

Vi fortsætter med at skrive koden fra den forrige rute.

$f3->route('GET /@code', // Angiv parameter efter "@", det vil blive i PARAMS
    function($f3) {

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

        $code = $f3->get('PARAMS.code'); // Får parameter

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

        // Hvis vi kan få linket fra databasen - få det, øg antal besøg og omdiriger
        if ($link->load(array('code="'.$code.'"', 'link=?'))) {
            $link->hits++;
            $link->save();

            $f3->reroute($link->link);
        } else {
            $f3->reroute('/'); // Hvis der ikke findes sådan et link - velkommen tilbage til forsiden
        }
    }
);

Du har måske bemærket, at i og i ruten newLink, og i den nævnte rute vil det defineres ens — for code kan være det samme som "newLink" (det kan ikke, i generatoren er der kun store bogstaver), men da det blev defineret først, vil det blive udført først.

$f3→run()!

Tak for læsningen!
Jeg ville være glad, hvis du skrev en kommentar og rettede, hvis der er noget galt.

Og som en hjemmearbejde eller bevis på min dovenskab (mig), efterlader jeg en liste over, hvad der kan gøres. For det er bedre at lære i praksis!

  • Det er selvfølgelig usandsynligt, men ved generering $g_code kan blive gentaget, så jeg foreslår, at du skriver en funktion, der vil tjekke dette.
  • Du kan også lave en ordentlig statistik og vise det ved klik på /@code/stats
  • Forbyde at oprette links til selve linkforkortelsestjenesten, oprette en liste over "beskyttede" ressourcer fra forkortelse
  • Jeg anbefaler kraftigt også at lave inputvalidering på serversiden, med relevante fejlmeddelelser, man skal ikke stole på at tilføje attributten required og type="url" til inputfeltet
    RedComrade

  • Foreslå i kommentarerne…

    På linjen)

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster