无脂肪缩短链接 (F3)

无脂肪缩短链接 (F3)

在 13 岁的时候缩短链接并不丢脸,对吧? 初学者,而且不仅仅是初学者,应该在学习一些新框架的同时尝试编写自己的 Link Tamer。 这就是我所做的。 我能说什么 - 第五个引导程序,一个低脂肪框架和一个灵魂。

这里 演示,但 。 对于像我这样的读者😉

框架,对吗?

当然不是 Laravel 之类的 - 今天我们就用 65 KB 凑合 无脂框架。 如果你熟悉 Python Flask,你会感觉这已经在某个地方完成了:

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

好吧,算了。 下载 来自异地的 .zip,将其解压到一个文件夹中,该文件夹同时在您最喜欢的代码编辑器中打开。 清除 的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'); //рендерим шаблон
    }
);

现在您需要编写这个模板。 为了简单起见,我使用了 引导程序 v5 alpfa。

不要忘记在文件夹中创建所有模板 用户界面, 否则他们 不会 对框架可见

<!-- Файл: 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="/zh-CN/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,则创建一个新数据库“链接”然后运行这个 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 个字符,通过它进行重定向,例如 example.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) 模板非常相似的模板 - ”新链接.htm".
在那里,我们将显示已经缩短的链接及其点击次数(要再次查看这些“统计信息”,您需要再次缩短相同的链接 - 地址将保持不变)。
为了产生输出,我们将使用“变量传递”技巧:

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

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

这是清单 新链接.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="/zh-CN/">Главная</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="/zh-CN/" 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. 利润!

上一条Route之后我们继续写代码。

$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→运行()!

谢谢阅读!
如果您写下评论并纠正我(如果有问题),我会很高兴。

作为家庭作业或作者(我)懒惰的证明,我留下了一份可以做什么的清单。 最好边做边学!

  • 这当然不太可能,但是当生成时 $g_代码 可能会再次发生,所以我建议你编写一个函数来检查这一点。
  • 也可以进行正常统计并切换到后显示 /@代码/统计
  • 禁止创建指向链接缩短服务本身的链接,创建“受保护”免受缩短的资源列表
  • 我强烈建议,即使是这么小的事情,你也可以在服务器端进行输入验证,并显示相应的错误,你不应该依赖于在输入字段中添加 required 属性和 type = “url”
    红色同志

  • 在评论中提出建议...

    联系)

来源: habr.com

添加评论