Skrajšamo povezave brez dodatkov (F3)

Skrajšamo povezave brez dodatkov (F3)

Skratiti linke pri 13 letih ni sramota, kajne? Tudi začetniki, pa ne samo oni, bi morali poskusiti ustvariti svoj Kratica Linkov, ob tem pa raziskovati kakšen nov okvir. Tako sem tudi jaz ravnal. Kaj naj rečem — peti bootstrap, razmaščeni okvir in delček duše.

Evo demo, a evo kodo. Za takšne bralce, kot sem jaz 😉

Okvir, kajne?

Seveda ne Laravel in podobno — danes se bomo zadovoljili s 65 kilobajti. FatFreeFramework. Če ste seznanjeni s Python Flask, boste imeli občutek, da je to že nekje bilo:

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

No, pozabite. Prenesemo .zip z uradne strani, razpakiramo v mapo, ki se v tem trenutku odpre v vašem Ljubem Urejevalniku Kode. Očistite index.php in izbrišite vse iz /ui.

Tukaj je vse zelo preprosto — v mapi ui imamo vse Poglede, ali po domače — napredne HTML predloge, ki jih bomo prikazovali uporabniku ob dostopu na določen URL.

Tukaj je okvir našega "aplikacije":

<?php
//Datoteka: index.php

//Kickstart okvir
$f3=require('lib/base.php');
$f3->set('DEBUG', 1);
if ((float)PCRE_VERSION<8.0)
    trigger_error('PCRE različica je zastarela');
$f3->config('config.ini');

//VSE DRUGO KODO BOMO PISALI TU

$f3->run();

To je vse, kar morate vedeti za začetek. Začnimo s kodiranjem!

[za razvoj sem uporabil lokalni XAMPP na Windows in VS Code, članek je napisan v Notion-u]

Homepage

Začeli bomo z glavno stranjo. Logično, kajne?

//Файл: index.php

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

Zdaj je potrebno napisati to predlogo. Za enostavnost sem uporabil bootstrap v5 alpfa.

Ne pozabite ustvariti vseh predlog v mapi ui, saj sicer ne bodo vidne okvirju

<!-- Файл: 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>Pišemo (kodo), skrajšujemo (povezave)!</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="#">Članek na Habré</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Ustvarjalec</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Kratke povezave so že tukaj.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/sl/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">Vnesite povezavo:</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">Skrajšaj!</button>
                </div>
            </div>
        <input type="hidden" name="trp-form-language" value="sl"/></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">Narejeno z <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="ljubeznijo">, <a href="https://v5.getbootstrap.com/">petim Bootstrapom</a>    in <a href="https://fatfreeframework.com/">brez maščobe</a></footer>
        </div>
    </body>
</html>

In to je to, že imamo delujočo glavno stran. Oblika pošilja POST zahtevo s povezavo, ki jo je treba skrajšati.
Zdaj pa tisto najzanimivejše (ne).

Delo z BDP

Ustvarimo BDP — MySQL. Če imate nameščen PhpMyAdmin, ustvarite novo BDP "linker", nato pa izvedite to 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`);

Imeli bomo 3 polja za vsak link:

  1. Code — to so naključni 4 znaki po domeni, po katerih bo potekalo preusmerjanje, v obliki example.com/ABC1
  2. Link — Ne skrajšana povezava.
  3. Hits — število prehodov preko skrajšane povezave.

Na kratko bom opisal princip dela z BDP, brez dodatkov.

set('result', $db->exec('SELECT * FROM wherever')); 
// biće dostupni u šablonima, kao 

// Ili se može koristiti ugrađeni SQL Mapper:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); // sada su dostupne sve kolone reda, gde je link na Habr:
$row_value = $row->somerow; // Ovako

// Naravno, moguće je menjati vrednosti:
$row->link = 'https://habr.com';
$row->save(); // promene treba sačuvati, šta ste mislili?

// Više informacija o radu sa bazom podataka dostupno je ovde: https://a.nikonovs.ru/MPHR Preporučujem da pročitate, makar uz pomoć prevodioca ugrađenog u pretraživač.
?>

Prelazimo na skraćivanje.

Obrada nove veze

Kreiramo novu Vyušku u index'u, koja će obrađivati zahtev iz forme na glavnoj stranici.

Najpre ćemo kreirati novu, ali veoma sličnu prvu (home.htm) šablon — "newLink.htm".
Tamo ćemo ispisivati već skraćenu vezu i broj prelaza na nju (da bismo ponovo videli ovu "statistiku", potrebno je ponovo skratiti istu vezu — adresa će ostati ista).
Za ispis koristićemo trik sa "prelazom varijabli":

set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
// sada u šablonu možemo koristiti:

A evo i listinga 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>Pišemo (kodo), skrajšujemo (povezave)!</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="/sl/">Domov</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Članek na Habré</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Ustvarjalec</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Kratke povezave so že tukaj.</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">Zmanjšano:</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 na to povezavo: ``</p>
        <input type="hidden" name="trp-form-language" value="sl"/></form>

        <a href="/sl/" class="mt-3 mb-5 btn btn-primary btn-lg">VRNI SE NA DOMOV</a>

        <footer class="m-2">Narejeno z <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="ljubeznijo">, <a href="https://v5.getbootstrap.com/">petim Bootstrapom</a>    in <a href="https://fatfreeframework.com/">brez maščobe</a></footer>
        </div>
    </body>
</html>

Pišemo sam rout.

$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 for generating 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; // If the link is repeated, show the old code
            }

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

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

            if (!empty($f3->get('POST'))) { // Output 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 main
                $f3->$f3->reroute('/');
            }

        }
);

Done! It was actually simple.

Redirect

The job is almost done:

  1. Get the parameter from the URL
  2. Check its existence in the database
  3. Retrieve the corresponding link from the database
  4. Redirect the user
  5. Profit!

Let's continue writing code after the last route.

$f3->route('GET \/@code', \/\/ Define the parameter after "@", it will be in 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 - retrieve it, increase the number of accesses 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 homepage
        }
    }
);

You may have noticed that in the route newLink, and in the route above, the same thing is defined — after all, code it may match "newLink" (it can't, because in the generator only uppercase letters are allowed), but since it is defined first, it will execute first.

$f3→run()!

Hvala za branje!
I would be glad if you write a comment and correct me if something is wrong.

And as homework or a proof of the author's laziness (me), I leave a list of what you can do. After all, it's better to learn by doing!

  • It is of course unlikely, but during generation $g_code may repeat, so I suggest you write a function that will check this.
  • You can also create proper statistics and display it on the transition to /@code/stats
  • Prohibit creating links to the shortening service itself, create a list of "protected" resources that are not allowed to be shortened
  • I strongly recommend even in such a small matter to perform input validation on the server side, outputting appropriate errors, and not to rely on adding the required attribute and the type='url' to the input field.
    RedComrade

  • Suggest in the comments…

    Stay in touch)

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster