Συντόμευση συνδέσμων χωρίς λίπος (F3)

Συντόμευση συνδέσμων χωρίς λίπος (F3)

Δεν είναι ντροπή να συντομεύετε συνδέσμους στα 13, σωστά; Ένας αρχάριος, και όχι μόνο ένας αρχάριος, θα πρέπει να προσπαθήσει να γράψει το δικό του Link Tamer ενώ μαθαίνει κάποιο νέο πλαίσιο. Αυτό που έκανα. Τι μπορώ να πω - το πέμπτο bootstrap, ένα πλαίσιο με χαμηλά λιπαρά και ένα κομμάτι ψυχής.

Εδώ διαδήλωση, Αλλά η κώδικας. Για αναγνώστες σαν εμένα 😉

Πλαίσιο, σωστά;

Φυσικά όχι η Laravel και τα παρόμοια - σήμερα θα αρκεστούμε στα 65 kilobyte FatFreeFramework. Εάν είστε εξοικειωμένοι με το Python Flask, θα έχετε την αίσθηση ότι αυτό έχει ήδη γίνει κάπου:

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

Εντάξει, ξεχάστε το. Κατεβάστε .zip από offsite, αποσυσκευάστε το σε ένα φάκελο, ο οποίος την ίδια στιγμή ανοίγει στον Αγαπημένο σας Επεξεργαστή Κώδικα. Σαφή index.php και αφαιρέστε τα πάντα από /ui.

Όλα εδώ είναι εξαιρετικά απλά - στον φάκελο ui Έχουμε όλες τις Προβολές ή, για να το θέσω απλά, αναβαθμισμένα πρότυπα HTML που θα δείχνουμε στον χρήστη όταν αποκτήσει πρόσβαση σε μια συγκεκριμένη διεύθυνση URL.

Εδώ είναι ο σκελετός της «αίτησής» μας:

<?php
//Файл: index.php

// Kickstart the framework
$f3=require('lib/base.php');
$f3->set('DEBUG', 1);
if ((float)PCRE_VERSION<8.0)
    trigger_error('PCRE version is out of date');
$f3->config('config.ini');

//ВЕСЬ ОСТАЛЬНОЙ КОД БУДЕМ ПИСАТЬ ЗДЕСЬ

$f3->run();

Αυτό είναι το μόνο που χρειάζεται να γνωρίζετε για να ξεκινήσετε. Ας ξεκινήσουμε την κωδικοποίηση!

[για ανάπτυξη χρησιμοποίησα τοπικό XAMPP σε Windows και VS Code, άρθρο που γράφτηκε στο Noushen]

ΑΡΧΙΚΗ

Ας ξεκινήσουμε με την κεντρική σελίδα. Λογικό, σωστά;

//Файл: index.php

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

Τώρα πρέπει να γράψετε αυτό ακριβώς το πρότυπο. Για απλότητα χρησιμοποίησα bootstrap v5 alpfa.

Μην ξεχάσετε να δημιουργήσετε όλα τα πρότυπα στο φάκελο UI, αλλιώς αυτοί δεν θα ορατό στο πλαίσιο

<!-- Файл: 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>Пишем (код), сокращаем (ссылки)!</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="#">Главная</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Статья на Хабре</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Создатель</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Короткие ссылки уже здесь.</h1>

        <!-- Будем отправлять данные POST-запросом на /newLink -->
        <form class="mt-5 mb-3" action="/el/newLink/" method="POST">
            <div class="row justify-content-center">
                <div class="col-auto">
                <label for="inputLink" class="col-form-label">Введи ссылку:</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">Сократить!</button>
                </div>
            </div>
        </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">Сделано с <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="любовью">, <a href="https://v5.getbootstrap.com/">пятым Bootstrap'ом</a>    и <a href="https://fatfreeframework.com/">без жира</a></footer>
        </div>
    </body>
</html>

Αυτό είναι όλο, η κύρια σελίδα μας λειτουργεί ήδη. Η φόρμα στέλνει ένα αίτημα POST με έναν σύνδεσμο που πρέπει να συντομευτεί.
Τώρα έρχεται το διασκεδαστικό κομμάτι (όχι).

Εργασία με τη βάση δεδομένων

Ας δημιουργήσουμε μια βάση δεδομένων - MySQL. Εάν έχετε εγκαταστήσει το PhpMyAdmin, τότε δημιουργήστε μια νέα βάση δεδομένων "Links" και, στη συνέχεια, εκτελέστε αυτήν την 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`);

Θα έχουμε 3 πεδία για κάθε σύνδεσμο:

  1. Ο κώδικας είναι ένας τυχαίος 4 χαρακτήρες μετά τον τομέα μέσω του οποίου θα πραγματοποιηθεί ανακατεύθυνση, π.χ παράδειγμα.com/ABC1
  2. Σύνδεσμος - Δεν συντομεύτηκε Σύνδεσμος.
  3. Επισκέψεις - ο αριθμός των κλικ στον συντομευμένο σύνδεσμο.

Θα σας πω εν συντομία την αρχή της εργασίας με μια βάση δεδομένων, χωρίς λίπος.

<?php
//сначала нужно подключиться к БД
$db = new DBSQL(
    'mysql:host=localhost;port=3306;dbname=linker',
    'root',
    ''
);

//Дальше есть два варианда работы с данными:

//Можно установить переменную в Фреймворк c помощью обычного SQL-запроса:
$f3->set('result', $db->exec('SELECT * FROM wherever')); 
//они будут доступны в шаблонах, как <?= $resul ? >

//А можно использовать встроенный SQL Mapper:
$row = new DBSQLMapper($db, 'links');

$row->load(array('link="https://habrahabr.ru"')); //теперь из этого объекта доступны все колонки строки, где ссылка на Хабр:
$row_value = $row->somerow; //Вот так

// Естесственно можно изменять значения:
$row->link = 'https://habr.com';
$row->save(); //изменения нужно сохранить, а что вы думали

// больше информации по работе с БД доступно здесь: https://a.nikonovs.ru/MPHR Настоятельно рекомендую прочитать, хотябы с помощью переводчика, встроенного в браузер.
?>

Ας αρχίσουμε να κοντύνουμε.

Επεξεργασία νέου συνδέσμου

Δημιουργήστε μια νέα προβολή στο δείκτης, το οποίο θα επεξεργαστεί το αίτημα από τη φόρμα στην κεντρική σελίδα.

Αρχικά, ας δημιουργήσουμε ένα νέο, αλλά πολύ παρόμοιο με το πρώτο (home.htm) πρότυπο - "newLink.htm".
Εκεί θα εμφανίσουμε τον ήδη συντομευμένο σύνδεσμο και τον αριθμό των κλικ σε αυτόν (για να δείτε ξανά αυτά τα "στατιστικά", πρέπει να συντομεύσετε ξανά τον ίδιο σύνδεσμο - η διεύθυνση θα παραμείνει η ίδια).
Για να παράγουμε την έξοδο, θα χρησιμοποιήσουμε το τέχνασμα "μεταβλητής διέλευσης":

<?php
//Файл: нет (пример)

//устанавливаем переменную в index'е и рендерим шаблон
$f3->set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
//теперь в шаблоне можно использовать:
<?= $link ?>

Και εδώ είναι η λίστα 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>Пишем (код), сокращаем (ссылки)!</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="/el/">Главная</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Статья на Хабре</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="https://nikonovs.ru">Создатель</a>
                </li>
            </ul>
        </nav>

        <div class="container">
        <h1>Короткие ссылки уже здесь.</h1>

        <!-- Убираем из формы функционал формы и выводим переменные -->
        <form class="mt-5 mb-3">
            <div class="row justify-content-center">
                <div class="col-auto">
                    <label for="inputLink" class="col-form-label">Сократили:</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">По этой ссылке перешли: `<?= $hits ?>`</p>
        </form>

        <a href="/el/" class="mt-3 mb-5 btn btn-primary btn-lg">ВЕРНУТЬСЯ НА ГЛАВНУЮ</a>

        <footer class="m-2">Сделано с <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="любовью">, <a href="https://v5.getbootstrap.com/">пятым Bootstrap'ом</a>    и <a href="https://fatfreeframework.com/">без жира</a></footer>
        </div>
    </body>
</html>

Γράφουμε την ίδια τη διαδρομή.

$f3->route('GET|POST /newLink', //мы будем обрабатывать и POST и GET
    function($f3) {

            $db = new DBSQL( //Подключение к БД новое в каждом Роуте
                'mysql:host=localhost;port=3306;dbname=linker',
                'root',
                ''
            );

            //прекрасная функция генерации радомных символов:
            $permitted_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            function generate_string($input, $strength = 4) {
                $input_length = strlen($input);
                $random_string = '';
                for($i = 0; $i < $strength; $i++) {
                    $random_character = $input[mt_rand(0, $input_length - 1)];
                    $random_string .= $random_character;
                }

                return $random_string;
            }

            //проверка на повторение link - нам же не нужно чтобы каждый раз генерировались новые ссылки. link - уникальный.
            $check = new DBSQLMapper($db,'links');
            $check->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; //если link повторяется, то показываем старый код
            }

            $short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; //собираем конечную ссылку

            //параметры из $_POST можно получить с помощью $f3->get('POST'), поддерживается точечная нотация (поправьте, если неправильно называю): параметр "link" можно получить так: 
            $link = $f3->get('POST.link');

            if ( !empty($f3->get('POST')) ) { //Выдаем HTML, только если POST не пустой.

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

            } else { //иначе - редирект на главную
                $f3->$f3->reroute('/');
            }

        }
);

Ετοιμος! Στην πραγματικότητα, ήταν απλό.

Ανακατεύθυνση

Μένει μόνο λίγο να κάνουμε:

  1. Λήψη παραμέτρου από τη διεύθυνση URL
  2. Ελέγξτε την παρουσία του στη βάση δεδομένων
  3. Λάβετε τον αντίστοιχο σύνδεσμο από τη βάση δεδομένων
  4. Ανακατεύθυνση χρήστη
  5. Κέρδος!

Συνεχίζουμε να γράφουμε κώδικα μετά την τελευταία Διαδρομή.

$f3->route('GET /@code', //указываем параметр после "@", он попадет в PARAMS
    function($f3) {

        //снова определяем $db
        $db = new DBSQL(
            'mysql:host=localhost;port=3306;dbname=linker',
            'root',
            ''
        );

        $code = $f3->get('PARAMS.code'); //получаем параметр

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

        //если получается получить ссылку из БД - получаем, увеличиваем количество переходов и перенаправляем
        if ($link->load(array('code="'.$code.'"', 'link=?'))) {
            $link->hits++;
            $link->save();

            $f3->reroute($link->link);
        } else {
            $f3->reroute('/'); //а если такой ссылки нет - милости просим на главную
        }
    }
);

Ίσως το έχετε παρατηρήσει μέσα και στη διαδρομή νέοΣύνδεσμος, και στην παραπάνω διαδρομή θα οριστεί το ίδιο – άλλωστε κωδικός μπορεί να ταιριάζει με το "newLink" (δεν μπορεί, η γεννήτρια περιέχει μόνο κεφαλαία γράμματα), αλλά αφού ορίζεται πρώτα, θα εκτελεστεί πρώτα.

$f3→run()!

Ευχαριστώ για την ανάγνωση!
Θα χαρώ να γράψετε ένα σχόλιο και να με διορθώσετε αν κάτι δεν πάει καλά.

Και ως εργασία ή απόδειξη της τεμπελιάς του συγγραφέα (εγώ), αφήνω μια λίστα με το τι μπορεί να γίνει. Είναι καλύτερα να μαθαίνεις κάνοντας!

  • Αυτό είναι φυσικά απίθανο, αλλά όταν δημιουργείται $g_code μπορεί να συμβεί ξανά, γι' αυτό σας προτείνω να γράψετε μια συνάρτηση που θα το ελέγξει.
  • Μπορείτε επίσης να δημιουργήσετε κανονικά στατιστικά στοιχεία και να τα εμφανίσετε μετά την εναλλαγή σε /@code/stats
  • Απαγόρευση της δημιουργίας συνδέσμων προς την ίδια την υπηρεσία συντόμευσης συνδέσμων, δημιουργήστε μια λίστα πόρων που "προστατεύονται" από τη συντόμευση
  • Συνιστώ ανεπιφύλακτα ακόμη και σε ένα τόσο μικρό θέμα, να κάνετε επικύρωση εισόδου από την πλευρά του διακομιστή, με τα αντίστοιχα σφάλματα να εμφανίζονται, δεν πρέπει να βασίζεστε στην προσθήκη του απαιτούμενου χαρακτηριστικού και τύπου = "url" στο πεδίο εισαγωγής
    RedComrade

  • Προτείνετε στα σχόλια...

    Σε επαφή)

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο