Verkorten van links zonder vet (F3)

Verkorten van links zonder vet (F3)

Het is niet beschamend om al 13 jaar links te verkorten, toch? Zowel een beginner als een ervaren gebruiker zou moeten proberen zijn eigen Link Tamer te schrijven, terwijl hij een nieuw framework leert. Dat is precies wat ik deed. Wat kan ik zeggen — de vijfde bootstrap, een slank framework en een stukje ziel.

Hier is demo, maar code. Voor lezers zoals ik 😉

Een framework, nietwaar?

Natuurlijk geen Laravel en dergelijke — vandaag gaan we het doen met 65 kilobytes FatFreeFramework. Als je bekend bent met Python Flask, krijg je al snel het gevoel dat dit ergens anders al was:

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

Oké, laten we het vergeten. Downloaden we .zip van de officiële site, pak het uit in de map die op dat moment opent in je Favoriete Code Editor. Verwijder index.php en verwijder alles van /ui.

Hier is alles heel eenvoudig — in de map ui hebben we al onze Views, en als je het simpel wilt zeggen — opgewaardeerde HTML-sjablonen, die we aan de gebruiker laten zien bij toegang tot een specifieke URL.

Dit is het skelet van onze "applicatie":

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

// ALLE OVERIGE CODE SCHRIJVEN WE HIER

$f3->run();

Dat is alles wat je moet weten om te beginnen. Laten we beginnen met coderen!

[voor de ontwikkeling gebruikte ik een lokale XAMPP op Windows en VS Code, deze tekst is geschreven in Notion]

Homepage

Laten we beginnen met de startpagina. Logisch, toch?

//Файл: index.php

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

Nu moeten we deze sjabloon schrijven. Voor de eenvoud gebruikte ik bootstrap v5 alpha.

Vergeet niet om alle sjablonen in de map ui, anders zullen ze niet zichtbaar zijn voor het framework Dat is alles, we hebben al een werkende startpagina. Het formulier verzendt de link die verkort moet worden via een POST-verzoek.

<!-- Файл: 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>We schrijven (code), we verkorten (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="#">Home</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Artikel op Habré</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Maker</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Korte links zijn er al.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/nl/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">Voer de link in:</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">Verkorten!</button>
                </div>
            </div>
        <input type="hidden" name="trp-form-language" value="nl"/></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">Gemaakt met <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="met liefde">, <a href="https://v5.getbootstrap.com/">de vijfde Bootstrap</a>    en <a href="https://fatfreeframework.com/">zonder vet</a></footer>
        </div>
    </body>
</html>

Nu komt het interessante (niet).
Werken met de database

We zullen een database maken — MySQL. Als je PhpMyAdmin hebt geïnstalleerd, maak je een nieuwe database "

linker", en voer dan deze SQL uit: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`);

Elke link heeft 3 velden:

Code — dit zijn willekeurige 4 tekens na het domein, waarover de omleiding zal plaatsvinden, zoals

  1. example.com/ABC1 Link —
  2. De niet-verkorte link. Hits — het aantal klikken op de verkorte link.
  3. Samenvattend zal ik kort de werking van de database uitleggen, zonder poespas.

Ik zal kort uitleggen hoe je met de database werkt, zonder poespas.

set('result', $db->exec('SELECT * FROM wherever')); 
// Deze zijn beschikbaar in sjablonen als 

// Of je kunt de ingebouwde SQL Mapper gebruiken:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); // nu zijn alle kolommen van de rij waar de link naar Habr gaat beschikbaar:
$row_value = $row->somerow; // zo

// Natuurlijk kunnen we de waarden aanpassen:
$row->link = 'https://habr.com';
$row->save(); // wijzigingen moeten worden opgeslagen, wat dacht je

// Meer informatie over het werken met databases is hier beschikbaar: https://a.nikonovs.ru/MPHR Ik raad ten zeerste aan om het te lezen, al is het maar met behulp van de vertaler van de browser.
?>

Laten we beginnen met verkorten.

Verwerken van een nieuwe link

Laten we een nieuwe view creëren in index, die het verzoek van het formulier op de homepage zal verwerken.

Laten we eerst een nieuwe sjabloon maken, dat erg lijkt op de eerste (home.htm) — "newLink.htm".
Daar zullen we de verkorte link en het aantal klikken erop weergeven (om deze "statistieken" opnieuw te zien, moet je dezelfde link opnieuw verkorten — het adres blijft hetzelfde).
Voor de output gebruiken we de truc met "variabele overgangen":

set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
// Nu kan de sjabloon gebruiken:

En hier is de listing 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>We schrijven (code), we verkorten (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="/nl/">Home</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Artikel op Habré</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Maker</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Korte links zijn er al.</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">Ingekort:</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">Via deze link doorklikken: ``</p>
        <input type="hidden" name="trp-form-language" value="nl"/></form>

        <a href="/nl/" class="mt-3 mb-5 btn btn-primary btn-lg">TERUG NAAR DE STARTPAGINA</a>

        <footer class="m-2">Gemaakt met <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="met liefde">, <a href="https://v5.getbootstrap.com/">de vijfde Bootstrap</a>    en <a href="https://fatfreeframework.com/">zonder vet</a></footer>
        </div>
    </body>
</html>

Laten we de route schrijven.

$f3->route('GET|POST /newLink', // We will handle both POST and GET
    function($f3) {

            $db = new DBSQL( // New DB connection in each Route
                'mysql:host=localhost;port=3306;dbname=linker',
                'root',
                ''
            );

            // A great function to generate random characters:
            $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; // Show old code if the link is duplicated
            }

            $short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; // Assemble the final link

            // Parameters from $_POST can be obtained using $f3->get('POST'), point notation is supported (please correct me if I'm wrong): parameter "link" can be obtained like this: 
            $link = $f3->get('POST.link');

            if (!empty($f3->get('POST'))) { // Provide HTML only if POST is not empty.

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

            } else { // Otherwise - redirect to the main
                $f3->$f3->reroute('/');
            }

        }
);

Klaar! Eigenlijk was dit eenvoudig.

Redirectie

Het lijkt erop dat er nog maar een stap te gaan is:

  1. Verkrijg de parameter uit de URL
  2. Controleer of deze aanwezig is in de database
  3. Verkrijg de overeenkomstige link uit de database
  4. Verwijs de gebruiker door
  5. Winst!

We gaan verder met het schrijven van code na de vorige route.

$f3->route('GET /@code', // geef de parameter op na "@", die komt in PARAMS
    function($f3) {

        // opnieuw $db definiëren
        $db = new DBSQL(
            'mysql:host=localhost;port=3306;dbname=linker',
            'root',
            ''
        );

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

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

        // als het lukt om de link uit de DB te krijgen - verkrijg, verhoog het aantal klikken en omleiden
        if ($link->load(array('code="'.$code.'"', 'link=?'))) {
            $link->hits++;
            $link->save();

            $f3->reroute($link->link);
        } else {
            $f3->reroute('/'); // als zo'n link niet bestaat - welkom op de hoofdpagina
        }
    }
);

Je hebt misschien opgemerkt dat in de route newLink, en in de bovenstaande route is dezelfde - want code kan overeenkomen met "newLink" (kan niet, in de generator alleen hoofdletters), maar omdat hij eerst is gedefinieerd, wordt hij ook als eerste uitgevoerd.

$f3->run()!

Bedankt voor het lezen!
Ik zou het waarderen als je een opmerking schrijft en me corrigeert als er iets niet klopt.

En als huiswerk of bewijs van de luiheid van de auteur (mij), laat ik een lijst achter van wat je kunt doen. Want het is beter om praktisch te leren!

  • Het is natuurlijk onwaarschijnlijk, maar bij het genereren $g_code kan zich herhalen, dus ik stel voor dat je een functie schrijft die dit controleert.
  • Je kunt ook een goede statistiek maken en deze tonen bij klikken op /@code/stats
  • Verbied het maken van links naar de verkortingsservice zelf, maak een lijst van "beschermde" bronnen tegen verkorting
  • Ik raad ten zeerste aan om zelfs in zo'n klein geval invoervalidatie aan de serverzijde te doen, met het tonen van bijbehorende fouten, vertrouw niet alleen op het toevoegen van het attribuut required en type type="url" aan het invoerveld.
    RedComrade

  • Stel voor in de opmerkingen...

    In contact)

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster