
Raccourcir des liens pendant 13 ans n'est pas honteux, n'est-ce pas ? Même pour un débutant, il vaut la peine d'essayer d'écrire son propre Démolisseur de Liens, tout en apprenant un nouveau framework. C'est ce que j'ai fait. Que dire — le cinquième Bootstrap, un framework allégé et un peu de mon âme.
Voici , mais voici . Pour des lecteurs comme moi 😉
Un framework, n'est-ce pas ?
Bien sûr, ce n'est pas Laravel et d'autres semblables — aujourd'hui, nous nous contenterons de 65 kilo-octets . Si vous êtes familier avec Python Flask, vous aurez l'impression que cela a déjà été fait quelque part :
#роутинг во Фласке
@app.route('/')
def hello_world():
return 'Hello, World!'
//роутинг в Обезжиренном
$f3->route('GET /',
function() {
echo 'Hello, world!';
}
);D'accord, oubliez ça. Téléchargeons , décompressons dans le dossier qui s'ouvre immédiatement dans votre Éditeur de Code Préféré. Nettoyez index.php et supprimez tout ce qui se trouve dans /ui.
Ici, c'est très simple — dans le dossier ui , nous avons tous les Vues, ou si l'on veut simplifier — des modèles HTML améliorés que nous montrerons à l'utilisateur lorsqu'il accède à une URL spécifique.
Voici la structure de notre "application" :
<?php
//Fichier : index.php
// Démarrer le framework
$f3=require('lib/base.php');
$f3->set('DEBUG', 1);
if ((float)PCRE_VERSION<8.0)
trigger_error('La version de PCRE est obsolète');
$f3->config('config.ini');
//TOUS LE CODE RESTANT SERA ÉCRIT ICI
$f3->run();Voilà tout ce qu'il faut savoir pour commencer. Passons à la codification !
[pour le développement, j'ai utilisé un local sur Windows et VS Code, ]
Homepage
Commençons par la page d'accueil. Logique, n'est-ce pas ?
//Файл: index.php
$f3->route('GET /',
function($f3) { //чтобы использовать функции F3 передаем его в роут
$view = new View; // создаем вьюшку
echo $view->render('home.htm'); //рендерим шаблон
}
);Nous devons maintenant écrire ce modèle. Pour simplifier, j'ai utilisé
N'oubliez pas de créer tous les modèles dans le dossier ui, sinon ils ne seront pas visibles pour le 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>Nous écrivons (code), nous réduisons (liens) !</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="#">Accueil</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Article sur Habr</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://nikonovs.ru">Créateur</a>
</li>
</ul>
</nav>
<div class="container">
<h1>Les liens courts sont déjà ici.</h1>
<!-- Будем отправлять данные POST-запросом на /newLink -->
<form class="mt-5 mb-3" action="/fr/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">Entrez le lien :</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">Raccourcir !</button>
</div>
</div>
<input type="hidden" name="trp-form-language" value="fr"/></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">Fait avec <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="avec amour">, <a href="https://v5.getbootstrap.com/">le cinquième Bootstrap</a> et <a href="https://fatfreeframework.com/">sans graisse</a></footer>
</div>
</body>
</html>Et voilà, notre page d'accueil est déjà en marche. Le formulaire envoie un lien par requête POST qui doit être raccourci.
Maintenant, le plus intéressant (non).
Travailler avec la BDD
Créons une BDD — MySQL. Si vous avez PhpMyAdmin installé, créez une nouvelle BDD "linker", puis exécutez cette 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`);Nous aurons 3 champs pour chaque lien :
- Code — ce sont 4 caractères aléatoires après le domaine, selon lesquels le redirection se fera, comme example.com/ABC1
- Lien — Le lien non raccourci. Hits — le nombre de clics sur le lien raccourci.
- En bref, je vais vous expliquer le principe de fonctionnement de la BDD, sans fioritures.
Je vais expliquer brièvement le principe de travail avec les bases de données, sans fioritures.
set('result', $db->exec('SELECT * FROM wherever'));
//elle sera disponible dans les modèles comme
//Ou vous pouvez utiliser le SQL Mapper intégré :
$row = new DBSQLMapper($db, 'links');
$row->load(array('link="https://habrahabr.ru"')); //maintenant, depuis cet objet, toutes les colonnes de la ligne où le lien est sur Habr sont disponibles :
$row_value = $row->somerow; //voilà comment
// Vous pouvez bien sûr modifier les valeurs :
$row->link = 'https://habr.com';
$row->save(); //les modifications doivent être enregistrées, qu'en pensiez-vous ?
//plus d'informations sur le travail avec la base de données disponibles ici : https://a.nikonovs.ru/MPHR Je vous recommande vivement de lire, même en utilisant le traducteur intégré du navigateur.
?>Commençons à raccourcir.
Traitement d'un nouveau lien
Créons une nouvelle vue dans index.php, qui traitera la demande du formulaire sur la page d'accueil.
Tout d'abord, créons un nouveau modèle, très similaire au premier (home.htm) — "newLink.htm".
". C'est là que nous afficherons le lien raccourci et le nombre de clics sur celui-ci (pour voir à nouveau cette "statistique", vous devez de nouveau raccourcir ce même lien — l'adresse restera la même).
Pour l'affichage, nous allons utiliser une astuce avec "le passage de variables" :
set('link', $shorted_link);
$view = new View;
echo $view->render('newLink.htm');
//maintenant, vous pouvez utiliser dans le modèle :Et voici le 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>Nous écrivons (code), nous réduisons (liens) !</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="/fr/">Accueil</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Article sur Habr</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://nikonovs.ru">Créateur</a>
</li>
</ul>
</nav>
<div class="container">
<h1>Les liens courts sont déjà ici.</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">Réduit :</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">Accédé via ce lien : ``</p>
<input type="hidden" name="trp-form-language" value="fr"/></form>
<a href="/fr/" class="mt-3 mb-5 btn btn-primary btn-lg">RETOURNER À L'ACCUEIL</a>
<footer class="m-2">Fait avec <img width="20" height="20" src="https://image.flaticon.com/icons/svg/833/833472.svg" alt="avec amour">, <a href="https://v5.getbootstrap.com/">le cinquième Bootstrap</a> et <a href="https://fatfreeframework.com/">sans graisse</a></footer>
</div>
</body>
</html>Nous écrivons la route elle-même.
$f3->route('GET|POST /newLink', // nous allons traiter à la fois POST et GET
function($f3) {
$db = new DBSQL( // Connexion à la base de données, nouvelle à chaque route
'mysql:host=localhost;port=3306;dbname=linker',
'root',
''
);
// magnifique fonction générant des caractères aléatoires:
$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; // si le lien est répété, alors nous montrons l'ancien code
}
$short_link = 'https://'. $_SERVER['HTTP_HOST'] . '/' . $g_code; // assemblage du lien final
// les paramètres de $_POST peuvent être obtenus avec $f3->get('POST'), la notation par point est supportée (corrigez-moi si je me trompe): le paramètre "link" peut être obtenu ainsi:
$link = $f3->get('POST.link');
if ( !empty($f3->get('POST')) ) { // Affichons le HTML uniquement si POST n'est pas vide.
$f3->set('link', $short_link);
$f3->set('hits', $check->hits);
$view = new View;
echo $view->render('newLink.htm');
} else { // sinon - redirigeons vers la page d'accueil
$f3->$f3->reroute('/');
}
}
);C'est fait ! En réalité, c'était simple.
Redirection
Il ne reste plus qu'à :
- Obtenir un paramètre depuis l'URL
- Vérifier sa présence dans la base de données
- Obtenir le lien correspondant de la base de données
- Rediriger l'utilisateur
- Profit !
Continuons à écrire du code après le dernier route.
$f3->route('GET /@code', // specify the parameter after "@", it will go to PARAMS
function($f3) {
// again we 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 we can get the link from the database - we get 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 there is no such link - welcome to the main page
}
}
);Vous avez peut-être remarqué que dans le route newLink, et dans le route ci-dessus, il s’agit de la même chose — après tout, peut coïncider avec "newLink" (ce qui est impossible, dans le générateur, seules les lettres majuscules sont acceptées), mais comme il est défini en premier, il sera exécuté en premier.
$f3->run()!
Merci pour votre lecture !
Je serais ravi si vous laissez un commentaire et corrigez-moi si quelque chose ne va pas.
Et en guise de devoir ou preuve de paresse de l'auteur (moi), je laisse une liste de ce que l’on peut faire. Après tout, il vaut mieux apprendre par la pratique!
- C’est bien sûr peu probable, mais lors de la génération $g_code peut se répéter, alors je vous propose d'écrire une fonction qui vérifiera cela.
- On peut aussi faire des statistiques correctes et les afficher lors des transitions sur /@code/stats
- Interdire la création de liens vers le service de raccourcissement de liens lui-même, créer une liste "protégée" contre le raccourcissement des ressources
Je recommande vivement de faire une validation de l'entrée même dans un si petit projet côté serveur, avec des messages d'erreur appropriés; il ne faut pas compter uniquement sur l'ajout de l'attribut required et du type type="url" au champ d'entrée.
Suggérez dans les commentaires…
En ligne)
Source : habr.com
