Skracujeme odkazy bez zbytočných prvkov (F3)

Skracujeme odkazy bez zbytočných prvkov (F3)

Nie je hanba skracovať odkazy už 13 rokov, však? Začiatočník, a nielen ten, by mal skúsiť napísať svoj vlastný Scriber Odkazov a popritom sa učiť nový framework. Čím som sa aj zaoberal. Čo povedať — piaty Bootstrap, odtučnený framework a kúsok duše.

Tu sú demo, ale tu kód. Pre takých čitateľov, ako som ja 😉

Framework, že áno?

Samozrejme nie Laravel a podobné — dnes sa zaobídeme s 65 kilobajtmi. FatFreeFramework. Ak poznáte Python Flask, pocítite, že niečo podobné už existuje:

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

Dobre, zabudnite. Stiahneme si .zip z oficiálnej stránky, rozbalíme ho do priečinka, ktorý sa práve otvorí vo vašom Oblúbenom Editore Kódu. Vymažte index.php a odstráňte všetko z /ui.

Tu je všetko mimoriadne jednoduché — v priečinku ui máme všetky pohľady, a ak to povieme jednoducho — vylepšené HTML šablóny, ktoré budeme zobrazovať užívateľovi pri návšteve určitého URL.

Toto je kostra našej "aplikácie":

<?php
// Súbor: index.php

// Naštartujte framework
$f3=require('lib/base.php');
$f3->set('DEBUG', 1);
if ((float)PCRE_VERSION<8.0)
    trigger_error('Verzia PCRE je zastaraná');
$f3->config('config.ini');

// CELÝ ZBYTOK KÓDU BUDEME PÍSAŤ TU

$f3->run();

A to je všetko, čo potrebujete vedieť na začiatok. Poďme na kódovanie!

[na vývoj som použil lokálny XAMPP na Windows a VS Code, článok je napísaný v Notion]

Homepage

Začneme s hlavnou stránkou. Logické, že?

//Файл: index.php

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

Teraz treba napísať túto šablónu. Pre jednoduchosť som použil Bootstrap v5 alpha.

Nezabudnite vytvoriť všetky šablóny v priečinku ui, ináč nebudú nebudú viditeľné frameworku.

<!-- Файл: 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>Píšeme (kód), skracujeme (linky)!</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="#">Domov</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Článok na Habbre</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Tvorca</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Krátke odkazy sú už tu.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/sk/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">Zadaj odkaz:</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">Skrať!</button>
                </div>
            </div>
        <input type="hidden" name="trp-form-language" value="sk"/></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">Vyrobené s <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="láskou">, <a href="https://v5.getbootstrap.com/">piatym Bootstrapom</a>    a <a href="https://fatfreeframework.com/">bez zbytočností</a></footer>
        </div>
    </body>
</html>

A to je všetko, už máme funkčnú hlavnú stránku. Formulár posiela POST požiadavku s odkazom, ktorý je potrebné skrátiť.
Teraz prichádza to najzaujímavšie (nie).

Práca s DB

Stvoríme databázu — MySQL. Ak máte nainštalovaný PhpMyAdmin, vytvorte novú databázu "linker", a potom vykonajte tento 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`);

Každý odkaz bude mať 3 polia:

  1. Code — to sú náhodné 4 znaky po doméne, podľa ktorých bude prebiehať presmerovanie, v tvare example.com/ABC1
  2. Link — Nie skrátený odkaz.
  3. Hits — počet kliknutí na skrátený odkaz.

Stručne poviem princíp práce s databázou, bez zbytočností.

set('result', $db->exec('SELECT * FROM wherever')); 
// Budú dostupné v šablónach ako 

// Ale môžete použiť vstavaný SQL Mapper:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); // Teraz sú z tohto objektu prístupné všetky stĺpce riadku, kde odkazuje na Habr:
$row_value = $row->somerow; // Takto

// Samozrejme môžete meniť hodnoty:
$row->link = 'https://habr.com';
$row->save(); // Zmeny treba uložiť, čo ste si mysleli

// Viac informácií o práci s DB je dostupných tu: https://a.nikonovs.ru/MPHR Dôrazne odporúčam prečítať si, aspoň pomocou prekladača zabudovaného v prehliadači.
?>

Začíname so skracovaním.

Spracovanie nového odkazu

Vytvárame novú šablónu v indexe, ktorá bude spracovávať dopyt z formulára na hlavnej stránke.

Najprv vytvoríme nový, ale veľmi podobný prvému (home.htm) šablónu — "newLink.htm".
Tam budeme zobrazovať už skrátený odkaz a počet prekliknutí po ňom (aby ste znova videli túto "štatistiku", musíte znova skrátiť tento istý odkaz — adresa ostane rovnaká).
Na zobrazenie využijeme trik s "prenosom premenných":

set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
// teraz v šablóne môžete použiť:

A tu je výpis 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>Píšeme (kód), skracujeme (linky)!</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="/sk/">Domov</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Článok na Habbre</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Tvorca</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Krátke odkazy sú už tu.</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">Skrytý:</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">Prešli ste na tento odkaz: ``</p>
        <input type="hidden" name="trp-form-language" value="sk"/></form>

        <a href="/sk/" class="mt-3 mb-5 btn btn-primary btn-lg">NÁVRAT NA HLAVNÚ STRÁNKU</a>

        <footer class="m-2">Vyrobené s <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="láskou">, <a href="https://v5.getbootstrap.com/">piatym Bootstrapom</a>    a <a href="https://fatfreeframework.com/">bez zbytočností</a></footer>
        </div>
    </body>
</html>

Píšeme samotný rout.

$f3->route('GET|POST /newLink', // budeme spracovávať POST aj GET
    function($f3) {

            $db = new DBSQL( // Pripojenie k DB nové v každom Róte
                'mysql:host=localhost;port=3306;dbname=linker',
                'root',
                ''
            );

            // skvelá funkcia generovania náhodných symbolov:
            $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; // ak sa link opakuje, zobrazujeme starý kód
            }

            $short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; // zostavujeme konečný link

            // parametre z $_POST môžeme získať pomocou $f3->get('POST'), podporuje sa bodová notácia (opravte ma, ak to nazývam nesprávne): parameter "link" sa dá získať takto:
            $link = $f3->get('POST.link');

            if (!empty($f3->get('POST'))) { // Vydávame HTML, len ak nie je POST prázdny.

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

            } else { // inak - presmerovanie na hlavnú stránku
                $f3->$f3->reroute('/');
            }

        }
);

Hotovo! V skutočnosti to bolo jednoduché.

Presmerovanie

Zostáva len málo:

  1. Získať parameter z URL
  2. Overiť jeho prítomnosť v DB
  3. Získať z DB príslušný odkaz
  4. Presmerovať používateľa
  5. Zisk!

Pokračujeme v písaní kódu po predchádzajúcom Róte.

$f3->route('GET /@code', // specify the parameter after "@", it will go to PARAMS
    function($f3) {

        // redefine $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 able to retrieve the link from the DB - obtain 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 no such link exists - welcome to the homepage
        }
    }
);

You might have noticed that both in and in the route newLink, and in the above route will define the same thing — after all code may coincide with "newLink" (it cannot, the generator only allows uppercase letters), but since it is defined first, it will execute first.

$f3→run()!

Ďakujeme za prečítanie!
I would be glad if you wrote a comment and corrected me if something is wrong.

As a homework assignment or to prove the author's laziness (me), I leave a list of what can be done. After all, it's better to learn through practice!

  • This is of course unlikely, but during generation $g_code may repeat, so I suggest you write a function that will check it.
  • You can also create proper statistics and display them upon transition to /@code/stats
  • Prohibit creating links to the shortening service itself, create a list of resources "protected" from shortening
  • I strongly recommend even in such a small matter to validate the input on the server side, with appropriate error messages, you shouldn't rely on adding the required attribute and type type="url" to the input field
    RedComrade

  • Feel free to suggest in the comments…

    In touch)

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster