
Nu-ți e rușine să scurtezi linkuri la 13 ani, nu-i așa? Chiar și un novice, și nu doar el, ar trebui să încerce să scrie propriul său Îmblânzitor de Linkuri, în timp ce învață un nou framework. Asta am și făcut. Ce să spun — al cincilea Bootstrap, un framework fără grăsime și puțin din suflet.
Iată , dar iată . Pentru cititorii ca mine 😉
Framework, nu-i așa?
Desigur, nu Laravel și altele similare — astăzi ne descurcăm cu 65 de kilobyți . Dacă ești familiarizat cu Python Flask, vei avea impresia că deja ai întâlnit ceva asemănător:
#роутинг во Фласке
@app.route('/')
def hello_world():
return 'Hello, World!'
//роутинг в Обезжиренном
$f3->route('GET /',
function() {
echo 'Hello, world!';
}
);Bine, hai să uităm. Descărcăm , descompressăm în folderul care se deschide instantaneu în Editorul Tău Preferat de Cod. Curăță index.php și elimină tot din /ui.
Aici totul este extrem de simplu — în folderul ui avem toate Viziunile, iar ca să spunem simplu — șabloanele HTML îmbunătățite, pe care le vom arăta utilizatorului când accesează un anumit URL.
Iată structura aplicației noastre:
<?php
//Fișier: index.php
//Pornim framework-ul
$f3=require('lib/base.php');
$f3->set('DEBUG', 1);
if ((float)PCRE_VERSION<8.0)
trigger_error('Versiunea PCRE este învechită');
$f3->config('config.ini');
// TOT CODUL RĂMAS ÎL VOM SCRIE AICI
$f3->run();Iată tot ce trebuie să știi pentru început. Să trecem la codare!
[pentru dezvoltare am folosit local pe Windows și VS Code, ]
Homepage
Să începem cu pagina principală. Logic, nu-i așa?
//Файл: index.php
$f3->route('GET /',
function($f3) { //чтобы использовать функции F3 передаем его в роут
$view = new View; // создаем вьюшку
echo $view->render('home.htm'); //рендерим шаблон
}
);Acum trebuie să scriem acest șablon. Pentru simplitate, am folosit
Nu uita să creezi toate șabloanele în folderul ui, altfel ele nu vor fi vizibile pentru framework
<!-- Файл: 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>Scriem (cod), scurtăm (linkuri)!</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="#">Acasă</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Articol pe Habr</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://nikonovs.ru">Creator</a>
</li>
</ul>
</nav>
<div class="container">
<h1>Link-uri scurte sunt deja aici.</h1>
<!-- Будем отправлять данные POST-запросом на /newLink -->
<form class="mt-5 mb-3" action="/ro/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">Introdu un 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">Scurtează!</button>
</div>
</div>
<input type="hidden" name="trp-form-language" value="ro"/></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">Realizat cu <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="dragoste">, <a href="https://v5.getbootstrap.com/">Bootstrap 5</a> și <a href="https://fatfreeframework.com/">fără grăsimi</a></footer>
</div>
</body>
</html>Iată, pagina principală funcționează deja. Formularul trimite un POST-request cu linkul care trebuie scurtat.
Acum vine partea interesantă (nu).
Lucrul cu Baza de Date
Vom crea DB — MySQL. Dacă ai PhpMyAdmin instalat, creează o nouă DB "linker", apoi execută acest 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`);Vor fi 3 câmpuri pentru fiecare link:
- Cod — acele 4 caractere aleatorii după domeniu, prin care va avea loc redirecționarea, de tipul example.com/ABC1
- Link — Linkul original. Hits — numărul de accesări a linkului scurtat.
- Îți voi explica pe scurt principiul de lucru cu Baza de Date, fără grăsime.
Voi descrie pe scurt principiul de lucru cu baza de date, fără detalii inutile.
set('result', $db->exec('SELECT * FROM wherever'));
//ele vor fi disponibile în șabloane, ca
//Sau putem folosi SQL Mapper integrat:
$row = new DBSQLMapper($db, 'links');
$row->load(array('link="https://habrahabr.ru"')); //acum din acest obiect sunt disponibile toate coloanele liniei, unde linkul este către Habr:
$row_value = $row->somerow; //Așa
//Desigur, putem modifica valorile:
$row->link = 'https://habr.com';
$row->save(); //modificările trebuie salvate, ce ați crezut
//mai multe informații despre lucrul cu baza de date sunt disponibile aici: https://a.nikonovs.ru/MPHR Vă recomand să citiți, cel puțin cu ajutorul traductorului integrat în browser.
?>Începem să scurtăm.
Prelucrarea unui link nou
Cream un nou șablon în index’e, care va prelucra cererea din formularul de pe pagina principală.
Mai întâi, să creăm un nou șablon, dar foarte asemănător cu primul (home.htm) — "newLink.htm".
Acolo vom afișa deja linkul scurtat și numărul de accesări ale acestuia (pentru a vedea din nou această "statistică", trebuie să scurtăm din nou același link — adresa va rămâne aceeași).
Pentru afișare, vom folosi un truc cu "transmiterea variabilelor":
set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
//acum în șablon putem folosi:Și iată listarea 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>Scriem (cod), scurtăm (linkuri)!</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="/ro/">Acasă</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Articol pe Habr</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://nikonovs.ru">Creator</a>
</li>
</ul>
</nav>
<div class="container">
<h1>Link-uri scurte sunt deja aici.</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">Scurtat:</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">Au accesat acest link: ``</p>
<input type="hidden" name="trp-form-language" value="ro"/></form>
<a href="/ro/" class="mt-3 mb-5 btn btn-primary btn-lg">ÎNTOARCE-TE LA PAGINA PRINCIPALĂ</a>
<footer class="m-2">Realizat cu <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="dragoste">, <a href="https://v5.getbootstrap.com/">Bootstrap 5</a> și <a href="https://fatfreeframework.com/">fără grăsimi</a></footer>
</div>
</body>
</html>Scriem ruta.
$f3->route('GET|POST /newLink', // vom procesa atât POST, cât și GET
function($f3) {
$db = new DBSQL( // Conectare la baza de date nouă pentru fiecare rută
'mysql:host=localhost;port=3306;dbname=linker',
'root',
''
);
// O funcție minunată pentru generarea de caractere aleatorii:
$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; // dacă linkul se repetă, arătăm codul vechi
}
$short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; // construim linkul final
// Parametrii din $_POST pot fi obținuți cu $f3->get('POST'), se suportă notația punctată (corectați-mă dacă greșesc): parametrul "link" poate fi obținut astfel:
$link = $f3->get('POST.link');
if ( !empty($f3->get('POST')) ) { // Furnizăm HTML, doar dacă POST nu este gol.
$f3->set('link', $short_link);
$f3->set('hits', $check->hits);
$view = new View;
echo $view->render('newLink.htm');
} else { // altfel - redirecționare către pagina principală
$f3->$f3->reroute('/');
}
}
);Este gata! De fapt, a fost simplu.
Redirecționare
Ceea ce rămâne de făcut este:
- Obține parametrul din URL
- Verifică dacă există în Bază de Date
- Obține linkul corespunzător din Baza de Date
- Redirecționează utilizatorul
- Profit!
Continuăm să scriem cod după ultima rută.
$f3->route('GET /@code', //specifying the parameter after "@", it will go to 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 it is possible to get the link from the DB - retrieve it, increase the number of hits and redirect
if ($link->load(array('code="'.$code.'"', 'link=?'))) {
$link->hits++;
$link->save();
$f3->reroute($link->link);
} else {
$f3->reroute('/'); //if such a link does not exist - welcome to the homepage
}
}
);You may have noticed that in the route newLink, and in the route above it defines the same thing — after all, it can coincide with "newLink" (it cannot, in the generator only uppercase letters are allowed), but since it is defined first, it will be executed first.
$f3->run()!
Thank you for reading!
I would be glad if you write a comment and correct me if anything is wrong.
And as homework or proof of the author's laziness (me), I leave a list of what can be done. 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 to check this.
- You can also make proper statistics and display it when transitioning to /@code/stats
- Prohibit creating links to the shortening service itself, create a list of "protected" resources that cannot be shortened
I strongly recommend even in such a small task to perform input validation on the server side and output appropriate errors, do not rely on adding the required attribute and type="url" to the input field
Suggest in the comments...
In touch)
Sursa: habr.com
