Vous travaillez principalement dans src, routes, phpaml.json et .env. AML gère runtime. Cette frontière protège le moteur et garde la racine compréhensible.
Avant de parcourir les dossiers
L’architecture est une carte de responsabilités.
Une bonne structure ne sert pas à multiplier les dossiers. Elle répond rapidement à une question : où placer ce code pour qu’un autre développeur comprenne son rôle sans l’ouvrir ? PHPAML sépare donc l’entrée HTTP, les routes, la coordination, les règles métier, la présentation et l’infrastructure générée.
- Une URL est déclarée dans routes/.
- Une action HTTP est coordonnée par un contrôleur.
- Une règle métier appartient à un modèle ou un service.
- La présentation appartient à src/views.
Carte du projet
Une place pour chaque responsabilité.
La structure du modèle officiel PHPAML.
my-project/
├── src/
│ ├── controllers/HomeController.php
│ ├── models/Home.php
│ └── views/{pages,components}/
├── routes/webapp.php
├── public/index.php # web entry point
├── phpaml.json # editable settings
├── .env # local secrets
└── runtime/ # AML-managed engine
├── storage/database.sqlite
└── database/migrations/Comprendre MVC
MVC divise l’application en responsabilités claires. Le modèle représente les données et les règles métier. Le contrôleur reçoit la requête et coordonne le travail. La vue produit le HTML envoyé au navigateur.
Contrôleurs et modèles
Les contrôleurs vivent dans src/controllers. Les modèles vivent dans src/models et concentrent l’accès aux données ainsi que la logique métier.
namespace App\Controllers;
final class HomeController
{
public function index(): array
{
return ['message' => 'Hello PHPAML'];
}
}Vues et composants
Les vues vivent dans src/views. Les pages composent l’écran; les composants isolent les éléments réutilisables. Une vue reçoit les données préparées par le contrôleur.
<?php require __DIR__ . '/partials/header.php'; ?>
<h1><?= htmlspecialchars($message) ?></h1>
<?php require __DIR__ . '/partials/footer.php'; ?>Routes et configuration
routes/webapp.php relie les URL aux contrôleurs. phpaml.json contient les réglages modifiables du projet; les secrets restent dans .env. La configuration interne générée appartient au runtime.
use App\Controllers\HomeController;
Route::get('/', [HomeController::class, 'index']);{
"name": "my-project",
"type": "webapp",
"language": "en"
}Base de données et migrations
SQLite pointe par défaut vers runtime/storage/database.sqlite. Les migrations générées restent dans runtime/database/migrations afin que la structure soit reproductible et versionnée.
runtime/database/migrations/Migrations généréesruntime/storage/database.sqliteBase locale généréeSurface publique
public/index.php reçoit les requêtes web. Les documents exigeant une URL directe, comme favicon, robots.txt ou sitemap.xml, peuvent rester dans public. Le code et les secrets n’y vont jamais.
Le runtime géré par AML
runtime contient le framework, l’autoloader, Composer, le stockage et les caches. phpaml.json identifie le projet et les versions attendues. AML génère et met à jour le runtime avec aml install.
src/ · routes/ · phpaml.json · .envruntime/Approfondissez chaque responsabilité
Comprendre avant de commencer à coder.
Relisez maintenant l’architecture comme le trajet d’une information, et non comme une liste de dossiers à mémoriser. Les situations suivantes expliquent les choix que vous devrez faire dans un vrai projet.
Comprendre MVC
Imaginez une bibliothèque en ligne. Sans organisation, un même fichier lirait l’URL, interrogerait SQLite, calculerait les droits de lecture et écrirait le HTML. Cela fonctionne au début, mais chaque modification risque ensuite de casser tout le reste.
MVC évite ce mélange. Le contrôleur comprend l’intention : afficher le livre 42. Le modèle sait retrouver ce livre et appliquer ses règles. La vue sait présenter le titre, l’auteur et le bouton de lecture. Chaque couche connaît sa mission, mais aucune ne doit tout savoir.
MVC n’impose pas trois fichiers pour chaque page. Une page statique peut ne pas avoir de modèle; une API peut retourner du JSON sans vue. Demandez-vous toujours quelle responsabilité le code exerce.
Changer la couleur du titre concerne la vue. Interdire la lecture aux comptes expirés appartient au modèle ou à un service métier.
Contrôleurs et modèles
Le contrôleur est un chef d’orchestre, pas l’orchestre entier. Il reçoit les paramètres HTTP, vérifie leur forme, appelle le métier puis choisit la réponse.
Pour GET /books/42, il récupère 42, demande le livre au modèle, renvoie une page 404 s’il est absent, puis transmet le résultat à la vue. Il ne doit pas construire une longue requête SQL ni écrire des balises HTML.
Le modèle représente les données et leur comportement. Il garantit par exemple qu’un titre n’est jamais vide ou qu’une progression reste comprise entre 0 et 100. Ces règles sont alors réutilisables depuis une page, une API, une commande ou un test.
Si une règle doit rester vraie lorsque l’interface change, elle ne devrait probablement pas vivre dans le contrôleur.
Vues et composants
Une vue reçoit un résultat déjà préparé. Elle ne décide pas quels livres le lecteur peut consulter; elle décide comment les afficher clairement et de manière accessible.
Une application PHPAML classique compose navigation, cartes, messages et pied de page. AML View exprime la même idée de façon déclarative avec des pages, composants, layouts et éléments comme VStack, Text ou Button.
Extrayez un composant lorsqu’un motif possède un sens propre ou se répète. Découper chaque ligne dans un fichier différent rend au contraire la lecture plus difficile.
Une vue peut formater une date, mais elle ne doit ni ouvrir la base ni contenir un secret. Échappez toute donnée provenant d’un utilisateur.
Routes et configuration
Une route est la porte d’entrée lisible d’une fonctionnalité. Elle associe une méthode HTTP et un chemin à une action : GET consulte, POST crée, PATCH modifie et DELETE supprime.
routes/webapp.php doit rester une carte, pas devenir un deuxième contrôleur. En le lisant, vous devez comprendre les URL publiques sans parcourir toute la logique métier.
phpaml.json décrit les choix partageables du projet. .env contient les valeurs propres à la machine et les secrets. Vous pouvez ainsi versionner le manifeste sans publier les identifiants de production.
Valeur partagée par l’équipe : phpaml.json. Valeur différente par machine ou secrète : .env.
Base de données et migrations
La base conserve l’état au-delà d’une requête. SQLite est idéale pour commencer : un fichier unique, aucun serveur séparé et un langage SQL familier.
Une migration décrit une transformation reproductible : créer la table books, ajouter published_at ou créer un index. Une modification manuelle ne peut pas être reproduite par les autres développeurs ou par le serveur.
PHPAML Data sera étudié plus tard : entités, ensembles typés, requêtes, relations et transactions sur SQLite, SQL ou MongoDB. Ici, retenez que les données relèvent du métier, tandis que le fichier SQLite généré relève du stockage du runtime.
database.sqlite n’est généralement pas versionné. Les migrations, elles, racontent l’histoire de la structure et doivent être conservées.
Surface publique
Le navigateur peut demander directement tout ce qui se trouve dans public. Cette propriété rend le dossier utile, mais aussi sensible.
public/index.php est le point d’entrée. favicon, robots.txt et sitemap.xml peuvent rester publics parce qu’ils exigent une URL directe.
À l’inverse, .env, phpaml.json, src et runtime ne doivent jamais être servis comme des fichiers. En production, la racine web de l’hébergeur doit viser public, pas le projet complet.
Avant d’ajouter un fichier, demandez-vous si n’importe qui devrait pouvoir le télécharger depuis son navigateur.
Le runtime géré par AML
runtime est la partie reconstruisible. AML y installe le framework, l’autoload, les dépendances privées, les caches, la configuration générée et certains fichiers de stockage.
Cette frontière garde la racine lisible et indique à AML ce qu’il peut mettre à jour. Une correction manuelle dans runtime disparaîtra lors d’une réinstallation.
Corrigez votre application dans src, routes, phpaml.json ou .env. Si le défaut appartient au framework, corrigez son dépôt et publiez une nouvelle version. runtime doit rester le résultat reproductible de aml install.
Le projet décrit l’application; runtime fournit et conserve son environnement d’exécution privé.
Exercice final
Classez les responsabilités.
Retrouvez la route, le contrôleur, le modèle, la page, les composants, phpaml.json, .env et SQLite. Expliquez le rôle de chacun sans ouvrir runtime.
Suivre une requête
De /movies à la réponse HTML.
- public/index.phpreçoit la requête et démarre l’application.
- routes/webapp.phpassocie GET /movies à une méthode de contrôleur.
- src/controllersvalide l’entrée et demande les données nécessaires.
- src/modelsapplique les règles métier et dialogue avec la persistance.
- src/viewstransforme les données préparées en interface.
Cette circulation est volontairement prévisible. Lorsqu’un écran affiche une mauvaise valeur, remontez le trajet : vue, contrôleur, modèle, puis source de données. Lorsqu’une URL ne répond pas, commencez par la route et non par le CSS.
Correction et pièges
Décidez par responsabilité, pas par habitude.
Ne placez pas une requête SQL dans une vue, un mot de passe dans phpaml.json ou une règle métier dans public/index.php. Ne modifiez pas runtime pour contourner un problème : corrigez la source du projet, puis laissez AML reconstruire l’infrastructure.
Mini-quiz : où placer un middleware ?
Dans src/middleware lorsqu’il s’agit de code applicatif. La configuration générée correspondante reste interne au runtime.