Skip to main content

Nouvelle page

Notes techniques — Site Erasmus+

Migration vers Fat Free Framework (F3)

Ce que nous avons mis en place, pourquoi, et comment ça fonctionne — expliqué simplement.



Migration vers

Fat
1Free Framework (F3)

1. 🗺️

Le contexte — d'd’où on part, où on va

Le site Erasmus+ a démarré en PHP pur : chaque page était un fichier PHP séparé (articles.php, contacts.php…). Simple à démarrer, mais difficile à faire évoluer sur le long terme.

On a décidé de migrer vers une architecture plus structurée, avec un framework léger. En bonus, on en a profité pour avoir de vraies URLs lisibles.

❌ Avant

(URLs moches“moches”)

:
Après (URLs propres)
erasmus.thymon.fr/article.php?id=corogna-2024

✅ Après

URLs propres :

erasmus.thymon.fr/article/corogna-2024

Ce changement nécessitait un point d'd’entrée unique : toutes les requêtes passent désormais par index.php, qui distribue le travail selon l'l’URL demandée. C'C’est ce que fait F3.



2.

2 🏗️

Le patron MVC — Modèle · Vue · Contrôleur

MVC est une façon d'd’organiser son code en 3 rôles bien séparés, pour ne pas tout mélanger dans un seul fichier.

🍕 Analogie — Un restaurant

Le Modèle = la cuisine. Il sait où sont les données et comment les lire (les fichiers JSON des articles).
La Vue = le menu et la salle. Elle s's’occupe uniquement de l'l’apparence (les fichiers HTML).
Le Contrôleur = le serveur. Il prend la commande (l'l’URL), va chercher les données, et les envoie à la bonne vue.

Schéma simple du flux :


Visiteur
→ frappe erasmus.thymon.fr/articles index.php — F3 lit l'URL et dit : "ça c'est pour ArticleController → liste()" ArticleController.php — va chercher les articles dans les JSON articles.html (Vue) — affiche les articles dans le HTML Navigateur reçoit la page finale

Avantage concret : si demain tu veux changer la mise en page de la liste des articles, tu touches seulement articles.html. Si tu veux changer comment les données sont filtrées, tu touches seulement ArticleController.php. Les deux ne se mélangent pas.


3 

3. ⚡ Fat Free Framework (F3) — le chef d'd’orchestre

F3 est un micro-framework PHP. "Framework"“Framework” = boîte à outils qui donne une structure. "Micro"“Micro” = il reste très léger, sans des dizaines de fichiers de configuration.

Son rôle principal dans notre projet : le routage. Il lit l'l’URL demandée et appelle le bon contrôleur.

// Dans index.php — on dit à F3 : "si quelqu'un va sur /articles,
// appelle la méthode liste() dans ArticleController"
$f3->route('GET /articles', 'ArticleController->liste');
$f3->route('GET /article/@slug', 'ArticleController->detail');
// @slug = la partie variable de l'URL (ex: "corogna-2024")

F3 s's’occupe aussi du moteur de templates : il lit les fichiers .html des vues, remplace les {{ @variables }} par les vraies valeurs, et produit le HTML final envoyé au navigateur.

💡 Pourquoi F3 plutôt que Laravel/Symfony ?


Les grands frameworks (Laravel, Symfony) sont très puissants mais ont une courbe d'd’apprentissage importante et beaucoup de "magie"“magie” cachée. F3 fait exactement ce dont on a besoin, sans surplus. Un seul fichier PHP de 200 Ko, aucune configuration complexe.


4 📦

4. 📦 Composer — le gestionnaire de librairies

Composer est le gestionnaire de paquets PHP. C'C’est l'l’équivalent ded’un ce qu'est l'App Store pour ton téléphonestore : il télécharge et installe des librairies quecréées d'par d’autres développeurs ont créées.développeurs.

🛒 Analogie — Liste de courses

Tu écris dans un fichier composer.json : "j'“j’ai besoin de F3 et de lad’une librairie pour manipuler des vidéos"vidéo”. Composer va sur internet, télécharge tout ça, et le place dans un dossier vendor/. Plus besoin de le faire manuellement.

On a installé deux librairies pour notrece projet :

  • bcosca/fatfree — le framework F3 lui-même
  • php-ffmpeg/php-ffmpegpourmanipulation manipuler des vidéosvidéo (génération de miniatures, futures fonctionnalités)

Le dossier vendor/ est exclu de Git (dans .gitignore) car il peut être recréé à tout moment avec la:

commande
composer install.

5 🔗

5. 🔗 Les URLs propres — comment ça fonctionne

Pour que toutes les URLs passent par index.php, on utilise un fichier .htaccess à la racine du site.site C'est un fichier de configuration Apache qui dit : "si le fichier ou dossier demandé n'existe pas physiquement, envoie la requête vers index.php"(Apache).

# .htaccess — la règle clé
RewriteEngine On
# Si ce n'est pas un vrai fichier ET pas un vrai dossier...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# ...redirige vers index.php
RewriteRule .* index.php [L,QSA]

Quand quelqu'quelqu’un va sur /article/corogna-2024 :

  1. Apache cherche un fichier article/corogna-2024n'n’existe pas
  2. La règle .htaccess envoie vers index.php
  3. F3 lit l'l’URL, détecte que c'est la route /article/@slug
  4. F3 appelle ArticleController->detail() avec slug = "corogna-2024"

⚠️ Piège important — Chemins relatifs


Avec les URLs propres, les chemins d'd’images relatifs cassent.cassent Sur: la pagesur /article/corogna-2024, une image uploads/photo.jpg est interprétée par le navigateur commedevient /article/uploads/photo.jpg → introuvable. Il faut toujours utiliserUtiliser des chemins absolus commençant par / : /uploads/photo.jpg.


6 🎨

6. 🎨 Les templates F3 — séparer le HTML du PHP

Dans l'l’ancien site, le PHP et le HTML étaient mélangés dans le même fichier.mélangés. Avec F3, le contrôleur prépare les données, puis les "envoie"“envoie” à un fichier HTML pur. Ce fichier HTML utilise une syntaxe spéciale pour afficher les données.(vue).

Syntaxe principale :

<!-- Afficher une variable (avec protection HTML automatique) -->
{{ @article.titre }}

<!-- Afficher du HTML pré-généré sans l'échapper -->
{{ @contenu_html | raw }}

<!-- Condition if/else -->
<check if="{{ @article.photo }}">
  <true><img src="{{ @article.photo }}" /></true>
  <false><div>Pas de photo</div></false>
</check>

<!-- Boucle foreach -->
<repeat group="{{ @articles }}" value="{{ @a }}">
  <h2>{{ @a.titre }}</h2>
</repeat>

F3 compile ces templates en PHP dans un dossier tmp/. Il ne recompile que si le fichier HTML source a changéchangé. Si c'estune plusvue rapide.ne Quandse onmet modifiepas unà template, on peutjour, vider le cache en supprimant les fichiers tmp/*.php.

📝 Analogie — Un formulaire à remplir

Le template HTML est comme un formulaire avec des cases vides. Le contrôleur PHP remplit les cases avec les vraies données. F3 est le mécanisme qui fait la liaison entre les deux.


7.


7 🗂️

Structure du projet — qui fait quoi


html/
 │ ├── index.php ← Point d'entrée UNIQUE (toutes les URLs arrivent iciici) └─ F3 lit l'URL et distribue au bon contrôleur │ ├── app/controllers/ Les CONTRÔLEURS (logique PHP) │ ├── BaseController.php ← La baseBase commune à tous (inject variables layout)layout, render...) │ ├── HomeController.php ← Gère la pagePage d'accueil (/) │ ├── ArticleController.php←php Gère /articles et /article/@slug │ ├── ContactController.php←php Gère /contacts │ └── StandardsController.php ← Gère /standards-qualite │ ├── app/views/ Les VUES (HTML pur + syntaxe F3) │ ├── layouts/ │ │ ├── main.html ← Layout page d'accueilAccueil (navbar complète + footer) │ │ └── simple.html ← Layout pagesPages secondaires (nav simplifiée)simplifiée + retour) │ ├── home.html │ ├── articles.html │ ├── article.html │ ├── contacts.html │ └── standards.html │ ├── includes/ ← Helpers PHP partagés │ ├── config.php ← Constantes (chemins) + chargement config.json │ ├── functions.php ← Fonctions utilitaires (charger_articles, email_encode...) │ └── db.php ← Connexion base de donnéesDB (pour futures fonctionnalités) │ ├── data/ Les DONNÉES (JSON, protégésprotégées par .htaccess) │ ├── articles/ ← 12 fichiers JSON (un par mobilité) │ ├── menu.json ← Structure du menu de navigation │ └── config.json ← ConfigurationConfig (email, mot de passemdp admin hashé) │ ├── vendor/ ← Librairies installées par Composer (ne pas modifier) └── admin/ ← Pages d'administration (migration F3 à venir)

8.

8 🖼️

Les layouts — le "moule"“moule” des pages

Un layout est le cadre commun à plusieurs pages. Au lieu de recopier la navbar et le footer dans chaque page,partout, on les met une seule fois dans le layout.

─────────────────── simple.html (layout) ──────────────────
│ <head> Tailwind CSS,Tailwind, polices, meta tags... │ │ ───────────────────────────────────────────────────────── --------------------------------------------------│ │ NAVBAR sticky (logo + lien retour) │ │ ───────────────────────────────────────────────────────── --------------------------------------------------│ │ │ │ {{ @content | raw }} │ │ ici s'insère la vue spécifiques'insère (articles.html, │ │ contacts.html, etc.)ici │ │ │ │ ───────────────────────────────────────────────────────── --------------------------------------------------│ │ FOOTER (liens navigation + copyright) │--------------------------------------------------│ │ ───────────────────────────────────────────────────────── │ │ {{ @extra_scripts | raw }} ← JS optionnel injecté ici │ └─────────────────────────────────────────────────────────────

On a deux layouts :

  • main.html — pour la page d'd’accueil (navbar aveccomplète + menu déroulant complet)déroulant)
  • simple.html — pour les pages secondaires (navbar allégée + lien "retour"“retour”)

9.

9 🛡️

PHP 8.4 — pièges rencontrés et leçons apprises

On tourne sur PHP 8.4, la: version la plus récente. Cette version est plus stricte que les anciennes :stricte, certaines choses qui "passaient"“passaient” avant provoquent maintenant des erreurs.

Piège n°1 — Variable non définie = erreur fatale

Si un template F3 essaie d'afficheraffiche {{ @ma_variable }} et que cette variable n'n’a pas été définie, PHP 8.4 lancepeut déclencher une erreur. En mode debug F3erreur (en DEBUG=3),3 ça se traduit par une: page blanche avec le code/ HTTP 500.500).

Solution : dans BaseController.php, on initialise toutesinitialiser les variables optionnelles àdans une valeur vide par défautBaseController.php :

// Dans BaseController::render()
$f3->set('page_description', '');
// ← valeur vide par défaut
$f3->set('extra_head',       '');
$f3->set('extra_scripts',   '');

Piège n°2 — Clé de tableau manquante

Accéder à $tableau['ma_cle'] quand la clé n'n’existe pas → "Undefined array key"key”. Par exemple, les types de modalités "groupe" et "enseignants-personnels" n'avaient pas de clé conditions, mais le template essayait d'y accéder.

Solution : toujours s'assurergarantir que toutes les clés existent, même avec une valeur videvides :

// Bien : la clé 'conditions' existe toujours (tableau vide si pas de conditions)
'groupe' => [
    'intro'      => "...",
    'items'      => [...],
    'conditions' => [], // vide mais présent
]

Comment diagnostiquer les erreurs :

On a une méthode efficace pour trouver les bugs rapidement :

  1. Dans index.php, mettre $f3->set('DEBUG', 3) pour activer le mode débogage
  2. Ajouter ini_set('error_log', __DIR__ . '/php_errors.log') pour écrire les erreurs dans un fichier
  3. Lire le fichier php_errors.log pour voir l'l’erreur exacte et la ligne concernée
  4. Une fois corrigé, remettre DEBUG=0 et supprimerretirer les lignes de loglogs
10 📖

10. 📖 Lexique — les termes à retenir


Terme
Définition
Framework
Boîte à outils qui impose une structure au projet. Plutôt
que deMVC toutOrganisation recoderdu depuiscode zéro,en on3 utiliserôles des outils existants et éprouvés.
MVCséparés (Modèle · Vue · Contrôleur)
.
Une
façon d'organiserRoute le code en 3 rôles séparés. Rend le code plus facile à maintenir et à faire évoluer.
Route
L'associationAssociation entre une URL (ex: /articles) et le code PHP à exécuter. C'est
F3 quiTemplate lit les routes définies dans index.php.
Template
Un fichierFichier HTML avec des "trous"“trous” ({{ @variable }}) queremplis lepar frameworkF3. remplit
avec lesLayout vraies données avant d'envoyer au navigateur.
Layout
Le cadreCadre commun à plusieurs pages (navbar + footer). Évitepartagé depar répéterplusieurs lepages. même
code dansComposer chaque page.
Composer
Gestionnaire de paquets PHP.PHP Télécharge etqui installe desles librairies externes dans le dossier vendor/.
.htaccess
FichierConfiguration deApache configurationqui du serveur web Apache. On l'utilise pour rediriger toutes les URLsredirige vers index.php (URLs propres).
Cache de templates
F3 compile sesles templates .html en PHP dans le dossier tmp/. Si une vue ne se metbouge pas à: jour, on vide ce cache en supprimant les fichierssupprimer tmp/*.php.
Chemin absolu vs relatif
Chemin absoluAbsolu = commence par /, toujours depuis la racine du site (/uploads/photo.jpg). Chemin relatifRelatif = depuisdépend lade page courante,l’URL, peut casser avec les URLsroutes. propres.
DEBUG=3 (F3)
Mode dedebug débogageF3 de: F3. Afficheaffiche les erreurs PHP en détail.erreurs. En productionprod on: met DEBUG=0. pour
cacher
les
erreurs
aux visiteurs.