Skracanie ogniw bez tłuszczu (F3)

Skracanie ogniw bez tłuszczu (F3)

Nie ma wstydu skracać linki w wieku 13 lat, prawda? Początkujący, i nie tylko początkujący, powinien spróbować napisać własnego Link Tamera, jednocześnie ucząc się nowego frameworka. I to właśnie zrobiłem. Cóż mogę powiedzieć – piąty bootstrap, low-fat framework i kawałek duszy.

tutaj jest próbny, Ale kod. Dla czytelników takich jak ja 😉

Ramy, prawda?

Oczywiście nie Laravel i tym podobne – dzisiaj poprzestaniemy na 65 kilobajtach FatFreeFramework. Jeśli znasz Python Flask, będziesz miał wrażenie, że gdzieś to już zostało zrobione:

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

Dobra, zapomnij o tym. Pobierać .zip z zewnętrznej witryny, rozpakuj go do folderu, który w tym samym momencie otworzy się w Twoim Ulubionym Edytorze Kodu. Jasne index.php i usuń wszystko z /ui.

Wszystko tutaj jest niezwykle proste - w folderze ui Mamy wszystkie widoki, czyli, mówiąc prościej, ulepszone szablony HTML, które pokażemy użytkownikowi, gdy uzyska dostęp do określonego adresu URL.

Oto szkielet naszej „aplikacji”:

<?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();

To wszystko, co musisz wiedzieć, aby zacząć. Zacznijmy kodować!

[do programowania użyłem lokalnego XAMPP na Windowsie i VS Code, artykuł napisany w Noushen]

Strona główna

Zacznijmy od strony głównej. Logiczne, prawda?

//Файл: index.php

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

Teraz musisz napisać ten sam szablon. Dla uproszczenia użyłem bootstrap v5 alfa.

Nie zapomnij utworzyć wszystkich szablonów w folderze interfejs użytkownika, inaczej oni nie będzie widoczne dla ramy

<!-- Файл: 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="/pl/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>

To wszystko, nasza strona główna już działa. Formularz wysyła żądanie POST z linkiem, który należy skrócić.
Teraz przychodzi zabawna część (nie).

Praca z bazą danych

Stwórzmy bazę danych - MySQL. Jeśli masz zainstalowany PhpMyAdmin, utwórz nową bazę danych „Linki", a następnie uruchom ten 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`);

Będziemy mieć 3 pola dla każdego linku:

  1. Kod to losowe 4 znaki po domenie przez którą nastąpi przekierowanie, np przykład.com/ABC1
  2. Link - Nie skrócony połączyć.
  3. Trafienia - liczba kliknięć w skrócony link.

Krótko opowiem Ci o zasadzie pracy z bazą danych, bez tłuszczu.

<?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 Настоятельно рекомендую прочитать, хотябы с помощью переводчика, встроенного в браузер.
?>

Zacznijmy skracać.

Przetwarzanie nowego łącza

Utwórz nowy widok w indeks, który przetworzy żądanie z formularza na stronie głównej.

Najpierw utwórzmy nowy, ale bardzo podobny do pierwszego szablonu (home.htm) - "nowyLink.htm".
Tam wyświetlimy już skrócony link i liczbę kliknięć w niego (aby ponownie zobaczyć te „statystyki”, trzeba ponownie skrócić ten sam link – adres pozostanie ten sam).
Aby wygenerować wynik, użyjemy sztuczki z „przekazywaniem zmiennych”:

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

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

A oto zestawienie nowyLink.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="/pl/">Главная</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="/pl/" 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>

Trasę piszemy sama.

$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('/');
            }

        }
);

Gotowy! Właściwie to było proste.

Przekierowanie

Jeszcze trochę zostało do zrobienia:

  1. Pobierz parametr z adresu URL
  2. Sprawdź jego obecność w bazie danych
  3. Pobierz odpowiedni link z bazy danych
  4. Przekieruj użytkownika
  5. Zysk!

Kontynuujemy pisanie kodu po ostatniej Trasie.

$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('/'); //а если такой ссылки нет - милости просим на главную
        }
    }
);

Być może zauważyłeś to na trasie i w jej trakcie nowyLink, a na trasie powyżej to samo zostanie zdefiniowane - mimo wszystko kod może pasować do „newLink” (nie może, generator zawiera tylko wielkie litery), ale ponieważ jest zdefiniowany jako pierwszy, zostanie wykonany jako pierwszy.

$f3 → uruchom()!

Dziękuje za przeczytanie!
Będzie mi miło, jeśli napiszesz komentarz i poprawisz mnie, jeśli coś jest nie tak.

A jako zadanie domowe lub dowód lenistwa autora (mnie) zostawiam listę tego, co można zrobić. Lepiej uczyć się poprzez działanie!

  • Jest to oczywiście mało prawdopodobne, ale podczas generowania $g_kod może się to powtórzyć, więc sugeruję napisanie funkcji, która to sprawdzi.
  • Możesz także tworzyć normalne statystyki i wyświetlać je po przełączeniu na /@kod/statystyki
  • Zabroń tworzenia linków do samej usługi skracania linków, stwórz listę zasobów „chronionych” przed skracaniem
  • Zdecydowanie zalecam aby nawet w tak drobnej sprawie wykonać walidację danych wejściowych po stronie serwera, z wyświetlonymi odpowiednimi błędami, nie należy polegać na dodaniu wymaganego atrybutu i wpisaniu = „url” w polu wejściowym
    Czerwony Towarzyszu

  • Zaproponuj w komentarzu...

    W kontakcie)

Źródło: www.habr.com

Dodaj komentarz