
Ridurre i link per 13 anni non è imbarazzante, vero? È un'ottima idea per i principianti, e non solo, provare a scrivere il proprio Url Shortener, magari mentre si esplora un nuovo framework. È proprio quello che ho fatto. Che dire, il quinto Bootstrap, un framework snellito e un pezzo della mia anima.
Ecco , ecco . Per lettori come me 😉
Un framework, giusto?
Certo, niente Laravel e simili—oggi ci baseremo su 65 kilobyte. . Se conosci Python Flask, ti sentirai come se l'avessi già visto da qualche parte:
#роутинг во Фласке
@app.route('/')
def hello_world():
return 'Hello, World!'
//роутинг в Обезжиренном
$f3->route('GET /',
function() {
echo 'Hello, world!';
}
);Va bene, dimentichiamo. Scarichiamo , estraiamo nella cartella che si apre immediatamente nel tuo Preferito Editor di Codice. Pulisci index.php ed elimina tutto da /ui.
Qui tutto è estremamente semplice: nella cartella ui abbiamo tutte le nostre viste, o per dirla semplicemente, template HTML potenziati che mostreremo all'utente quando accede a un determinato URL.
Ecco la struttura della nostra "applicazione":
set('DEBUG', 1);
if ((float)PCRE_VERSIONconfig('config.ini');
//TUTTO IL RESTO DEL CODICE VERRÀ SCRITTO QUI
$f3->run();Ecco tutto ciò che serve sapere per iniziare. Iniziamo a programmare!
[per lo sviluppo ho utilizzato il locale su Windows e VS Code, ]
Homepage
Iniziamo dalla homepage. Logico, vero?
//Файл: index.php
$f3->route('GET /',
function($f3) { //чтобы использовать функции F3 передаем его в роут
$view = new View; // создаем вьюшку
echo $view->render('home.htm'); //рендерим шаблон
}
);Ora dobbiamo scrivere questo template. Per semplicità ho usato
Non dimenticate di creare tutti i template nella cartella ui, altrimenti non saranno visibili al framework. Ecco fatto, abbiamo già la homepage funzionante. Il modulo invia un link che deve essere accorciato tramite una richiesta POST.
<!-- Файл: 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>Scriviamo (codice), accorciamo (link)!</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="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Articolo su Habr</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://nikonovs.ru">Creatore</a>
</li>
</ul>
</nav>
<div class="container">
<h1>Link brevi sono già qui.</h1>
<!-- Будем отправлять данные POST-запросом на /newLink -->
<form class="mt-5 mb-3" action="/it/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">Inserisci il 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">Accorcia!</button>
</div>
</div>
<input type="hidden" name="trp-form-language" value="it"/></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">Fatto con <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="amore">, <a href="https://v5.getbootstrap.com/">il quinto Bootstrap</a> e <a href="https://fatfreeframework.com/">senza fronzoli</a></footer>
</div>
</body>
</html>Ecco, abbiamo già la homepage funzionante. Il modulo invia un link tramite una richiesta POST che deve essere accorciato.
Ora la parte interessante (no).
Lavoro con il DB
Creiamo il database — MySQL. Se avete PhpMyAdmin installato, create un nuovo database "linker", e poi eseguite questo 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`);Avremo 3 campi per ogni link:
- Code — sono 4 caratteri casuali dopo il dominio, che saranno utilizzati per il reindirizzamento, del tipo example.com/ABC1
- Link — Il link originale. Hits — il numero di clic sul link accorciato.
- Riassumo brevemente il funzionamento del database, senza fronzoli.
Spiegherò brevemente il principio di funzionamento con i database, senza fronzoli.
set('result', $db->exec('SELECT * FROM wherever'));
// Saranno disponibili nei template come
// Oppure si può usare il mappatore SQL integrato:
$row = new DBSQLMapper($db, 'links');
$row->load(array('link="https://habrahabr.ru"')); // Ora da questo oggetto sono disponibili tutte le colonne della riga dove il link è su Habr:
$row_value = $row->somerow; // Ecco come
// Ovviamente, si possono modificare i valori:
$row->link = 'https://habr.com';
$row->save(); // Le modifiche devono essere salvate, cosa pensavate?
// Maggiori informazioni sul lavoro con il database sono disponibili qui: https://a.nikonovs.ru/MPHR Consiglio vivamente di leggerlo, anche solo con l'aiuto di un traduttore integrato nel browser.
?>Iniziamo a accorciare.
Elaborazione di un nuovo link
Creiamo una nuova vista in index’e, che gestirà la richiesta dal modulo sulla homepage.
Per prima cosa, creiamo un nuovo template, simile al primo (home.htm) — "newLink.htm".
Qui mostreremo il link accorciato e il numero di clic ricevuti su di esso (per visualizzare di nuovo queste "statistiche", sarà necessario accorciare di nuovo lo stesso link — l'indirizzo rimarrà lo stesso).
Per la visualizzazione, utilizzeremo un trucco con il "passaggio delle variabili":
set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
//ora nel template possiamo utilizzare:Ecco il listing 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>Scriviamo (codice), accorciamo (link)!</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="/it/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Articolo su Habr</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://nikonovs.ru">Creatore</a>
</li>
</ul>
</nav>
<div class="container">
<h1>Link brevi sono già qui.</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">Ridotto:</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">Siamo passati a questo link: ``</p>
<input type="hidden" name="trp-form-language" value="it"/></form>
<a href="/it/" class="mt-3 mb-5 btn btn-primary btn-lg">TORNA ALLA HOMEPAGE</a>
<footer class="m-2">Fatto con <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="amore">, <a href="https://v5.getbootstrap.com/">il quinto Bootstrap</a> e <a href="https://fatfreeframework.com/">senza fronzoli</a></footer>
</div>
</body>
</html>Scriviamo il routing.
$f3->route('GET|POST /newLink', // gestiremo sia POST che GET
function($f3) {
$db = new DBSQL( // Connessione al DB nuova in ogni Route
'mysql:host=localhost;port=3306;dbname=linker',
'root',
''
);
// fantastica funzione per generare caratteri casuali:
$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; // se il link si ripete, mostriamo il codice vecchio
}
$short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; // raccogliamo il link finale
// i parametri da $_POST possono essere ottenuti con $f3->get('POST'), supporta la notazione a punti (correggimi se sbaglio): il parametro "link" può essere ottenuto così:
$link = $f3->get('POST.link');
if ( !empty($f3->get('POST')) ) { // Forniamo HTML, solo se POST non è vuoto.
$f3->set('link', $short_link);
$f3->set('hits', $check->hits);
$view = new View;
echo $view->render('newLink.htm');
} else { // altrimenti - reindirizza alla home
$f3->$f3->reroute('/');
}
}
);Fatto! In realtà, è stato semplice.
Reindirizzamento
La parte restante è semplice:
- Ottenere il parametro dall'URL
- Controllarne la presenza nel DB
- Ottenere dal DB il link corrispondente
- Reindirizzare l'utente
- Profitto!
Continuiamo a scrivere codice dopo l'ultimo router.
$f3->route('GET /@code', //indica il parametro dopo "@", andrà nei PARAMS
function($f3) {
//di nuovo definiamo $db
$db = new DBSQL(
'mysql:host=localhost;port=3306;dbname=linker',
'root',
''
);
$code = $f3->get('PARAMS.code'); //otteniamo il parametro
$link = new DBSQLMapper($db,'links');
//se riusciamo a ottenere il link dal DB - lo otteniamo, incrementiamo il numero di click e reindirizziamo
if ($link->load(array('code="'.$code.'"', 'link=?'))) {
$link->hits++;
$link->save();
$f3->reroute($link->link);
} else {
$f3->reroute('/'); //se non esiste questo link - benvenuti nel principale
}
}
);Potresti aver notato che in entrambe le route newLink, e nella route sopra è definito lo stesso — poiché può coincidere con "newLink" (non può, nel generatore ci sono solo lettere maiuscole), ma poiché è definito prima, sarà eseguito per primo.
$f3→run()!
Grazie per la lettura!
Sarei felice se scrivessi un commento e correggessi eventuali errori.
Come compito a casa o come prova della mia pigrizia (me stesso), lascio un elenco di ciò che si può fare. È meglio imparare praticando!
- È ovviamente poco probabile, ma durante la generazione $g_code potrebbe ripetersi, quindi ti propongo di scrivere una funzione che lo verifichi.
- Inoltre, si può realizzare una statistica adeguata e mostrarla al momento del passaggio a /@code/stats
- Vietare la creazione di link al servizio di accorciamento URL, creare un elenco di risorse "protette" dall'accorciamento
Consiglio vivamente, anche in un compito così piccolo, di effettuare la validazione dell'input anche lato server, con la visualizzazione di errori appropriati; non è il caso di contare solo sull'aggiunta dell'attributo required e del tipo type="url" al campo di input.
Fai le tue proposte nei commenti…
In contatto)
Fonte: habr.com
