Accorcia i link senza spese eccessive (F3)

Accorcia i link senza spese eccessive (F3)

Accorciare i link a 13 anni non è imbarazzante, giusto? Anche un novizio, e non solo, dovrebbe provare a scrivere il proprio Url Shortener, mentre esplora un nuovo framework. Ed è proprio quello che sto facendo. Che dire — quinto bootstrap, un framework snello e un pezzo d'anima.

Ecco una demo, ma ecco codice. Per lettori come me 😉

Framework, giusto?

Certo, non Laravel e simili — oggi ci accontentiamo di 65 kilobyte FatFreeFramework. Se conosci Python Flask, avrai la sensazione che sia già stato fatto:

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

Va bene, dimentica. Scarica .zip dal sito ufficiale, estrailo nella cartella che si apre in questo momento nel tuo Editor di Codice Preferito. Pulisci index.php ed elimina tutto da /ui.

Qui tutto è estremamente semplice — nella cartella ui abbiamo tutte le nostre Views e, per dirla semplicemente, i template HTML potenziati che mostreremo all'utente quando accede a un determinato URL.

Ecco la struttura della nostra "applicazione":

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

//TUTTO IL RESTO DEL CODICE LO SCRIVEREMO QUI

$f3->run();

E questo è tutto ciò che devi sapere per cominciare. Iniziamo a programmare!

[per lo sviluppo ho utilizzato un locale XAMPP su Windows e VS Code, l'articolo è scritto in Notion]

Homepage

Iniziamo dalla pagina principale. Logico, vero?

//Файл: index.php

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

Ora dobbiamo scrivere questo template. Per semplicità ho usato bootstrap v5 alpha.

Non dimenticare di creare tutti i template nella cartella ui, altrimenti non saranno visibili al framework Ecco, la nostra pagina principale è già funzionante. Il modulo invia un link tramite una richiesta POST da accorciare.

<!-- Файл: 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>Scriviamo (codice), accorciamo (link)!</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="#">Articolo su Habr</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Creatore</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>I link brevi sono già qui.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/it/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">Inserisci il 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">Accorciare!</button>
                </div>
            </div>
        <input type="hidden" name="trp-form-language" value="it"/></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">Fatto con <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="con amore">, <a href="https://v5.getbootstrap.com/">il quinto Bootstrap</a>    e <a href="https://fatfreeframework.com/">senza fronzoli</a></footer>
        </div>
    </body>
</html>

Adesso la parte più interessante (no).
Lavoro con il database

Creiamo un database — MySQL. Se hai PhpMyAdmin installato, crea un nuovo database "

linker", e poi esegui questo 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`);

Avremo 3 campi per ogni link:

Code — sono 4 caratteri casuali dopo il dominio, che verranno utilizzati per il reindirizzamento, ad esempio

  1. example.com/ABC1 Link —
  2. il link non accorciato. Hits — il numero di clic sul link accorciato. Un breve riepilogo del funzionamento con il database, senza fronzoli.
  3. Riassumendo, spiegherò il funzionamento con il DB, senza fronzoli.

Spiegherò brevemente il principio di lavoro con i database, senza fronzoli.

set('result', $db->exec('SELECT * FROM wherever')); 
// saranno disponibili nei template come 

// Oppure è possibile utilizzare il SQL Mapper integrato:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); // ora da questo oggetto sono disponibili tutte le colonne della riga in cui il link è su Habr:
$row_value = $row->somerow; // Ecco come

// Naturalmente, è possibile modificare i valori:
$row->link = 'https://habr.com';
$row->save(); // le modifiche devono essere salvate, cosa pensavate?

// Maggiori informazioni su come lavorare con il database sono disponibili qui: https://a.nikonovs.ru/MPHR Consiglio vivamente di leggerlo, anche solo con l'aiuto di un traduttore incorporato nel browser.
?>

Iniziamo a accorciare.

Elaborazione di un nuovo link

Creiamo una nuova vista in index, che gestirà la richiesta dal modulo nella pagina principale.

Prima creiamo un nuovo template, che sarà molto simile al primo (home.htm) — "newLink.htm".
Qui mostreremo già il link accorciato e il numero di clic su di esso (per vedere di nuovo queste "statistiche" bisogna accorciare di nuovo lo stesso link — l'indirizzo rimarrà lo stesso).
Per la visualizzazione, utilizziamo un trucco con "il passaggio delle variabili":

set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
// ora nel template si può usare:

Ecco il 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>Scriviamo (codice), accorciamo (link)!</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="/it/">Home</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Articolo su Habr</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Creatore</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>I link brevi sono già qui.</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">Accorciato:</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">Si è cliccato su questo link: ``</p>
        <input type="hidden" name="trp-form-language" value="it"/></form>

        <a href="/it/" class="mt-3 mb-5 btn btn-primary btn-lg">TORNA ALL'INIZIO</a>

        <footer class="m-2">Fatto con <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="con amore">, <a href="https://v5.getbootstrap.com/">il quinto Bootstrap</a>    e <a href="https://fatfreeframework.com/">senza fronzoli</a></footer>
        </div>
    </body>
</html>

Scriviamo il routing.

$f3->route('GET|POST /newLink', //ci occuperemo di gestire sia POST che GET
    function($f3) {

            $db = new DBSQL( //Connessione al DB nuova in ogni Route
                'mysql:host=localhost;port=3306;dbname=linker',
                'root',
                ''
            );

            //meravigliosa funzione generatrice di caratteri casuali:
            $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; //se il link è duplicato, mostriamo il vecchio codice
            }

            $short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; //assemblare il link finale

            //i parametri da $_POST possono essere ottenuti con $f3->get('POST'), supporta la notazione puntata (correggere se non lo chiamo correttamente): il parametro "link" può essere ottenuto in questo modo: 
            $link = $f3->get('POST.link');

            if ( !empty($f3->get('POST')) ) { //forniamo HTML solo se POST non è vuoto.

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

            } else { //altrimenti - reindirizzamento alla homepage
                $f3->reroute('/');
            }

        }
);

Fatto! In realtà, era semplice.

Reindirizzamento

Rimane solo da fare:

  1. Ottenere il parametro dall'URL
  2. Controllare la sua presenza nel DB
  3. Ottenere dal DB il link corrispondente
  4. Reindirizzare l'utente
  5. Profitto!

Continuiamo a scrivere codice dopo l'ultima Route.

$f3->route('GET \/@code', \/\/indichiamo il parametro dopo "@", verrà inserito in PARAMS
    function($f3) {

        \/\/di nuovo definiamo $db
        $db = new DBSQL(
            'mysql:host=localhost;port=3306;dbname=linker',
            'root',
            ''
        );

        $code = $f3->get('PARAMS.code'); \/\/otteniamo il parametro

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

        \/\/se riusciamo a ottenere il link dal DB - lo otteniamo, aumentiamo il conteggio dei clic e reindirizziamo
        if ($link->load(array('code="'.$code.'"', 'link=?'))) {
            $link->hits++;
            $link->save();

            $f3->reroute($link->link);
        } else {
            $f3->reroute('\/'); \/\/se non esiste questo link, siete i benvenuti sulla homepage
        }
    }
);

Potreste aver notato che in e nel route newLink, e nel route sopra si definiscono le stesse cose — infatti code può coincidere con "newLink" (non può, nel generatore solo lettere maiuscole), ma poiché è stato definito per primo, verrà eseguito per primo.

$f3→run()!

Grazie per aver letto!
Sarei felice se scriveste un commento e correggeste se c'è qualcosa di sbagliato.

E come compito a casa o prova della pigrizia dell'autore (io), lascio un elenco di cose che si possono fare. Infatti, è meglio imparare praticando!

  • È ovviamente poco probabile, ma durante la generazione $g_code potrebbe ripetersi, quindi vi propongo di scrivere una funzione che lo controllerà.
  • Si può anche fare una statistica adeguata e mostrarla durante il passaggio a /@code/stats
  • Vietare la creazione di link al servizio stesso di accorciamento dei link, creare un elenco di risorse "protette" dall'accorciamento
  • Consiglio vivamente anche in un compito così piccolo di fare la validazione dell'input anche lato server, con la visualizzazione degli errori corrispondenti, non bisogna fare affidamento solo sull'aggiunta dell'attributo required e sul tipo type="url" al campo di input
    RedComrade

  • Fate proposte nei commenti...

    In contatto)

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster