ArtiFrame Documentation
Le framework pour des projets PHP natifs évolutifs, géré avec zéro dépendance externe, des règles strictes et une interface de ligne de commande puissante (CLI). Sans dépendances, libéré de la soupe de paquets Composer, un écosystème léger et rapide qui vous permet de vous concentrer sur votre logique métier.
Introduction & Philosophie
ArtiFrame est basé sur le principe de "Convention over Configuration" (Convention plutôt que Configuration). La force d'un framework ne vient pas de la richesse des outils qu'il propose, mais de la cohérence de l'ordre qu'il établit.
Zéro Surcharge (Zero Overhead)
Zéro dépendance aux paquets Composer, au cœur du framework ou aux bibliothèques tierces. Chaque ligne de code est la vôtre ; sans gonflement, sans couches d'abstraction inutiles.
La Sécurité d'Abord
La protection XSS, la validation CSRF, l'assainissement contre l'injection SQL et le contrôle de la méthode HTTP sont intégrés par défaut. La sécurité n'est pas une option, c'est un standard.
Ensemble de Règles Strict
Un développeur junior nouvellement intégré au projet comprend l'architecture data-js et la structure des répertoires en quelques minutes. La cohésion de l'équipe est garantie au niveau du framework.
Priorité à la CLI
Pas de création manuelle de fichiers view, API ou class. La CLI génère à partir de fichiers stub, établit des liens d'assets et maintient le projet cohérent.
Installation
ArtiFrame CLI est installé en tant qu'outil PHP global. Installé une fois, il est utilisé dans chaque projet.
1. Installer l'Outil CLI Globalement
# Installation globale via NPM
npm install -g @artilingo/artiframe-cli
# Vérifier l'installation
artiframe
2. Shell Interactif
Tapez simplement artiframe dans le terminal et appuyez sur Entrée. La CLI ne se ferme pas ; un shell interactif s'ouvre, à l'écoute des commandes en continu :
==================================================
ArtiFrame CLI Interactive Shell v1.0.0
==================================================
Type 'help' for commands, or 'exit' to quit.
artiframe>
3. Démarrer un Nouveau Projet
artiframe> new mon-projet
Cette commande crée le répertoire mon-projet/ et copie toute la structure squelette à l'intérieur : app/, bin/, config/, public/, src/, .env.example et la première page index.php.
4. Paramètres d'Environnement
cp .env.example .env
Ouvrez votre fichier .env et remplissez les informations de base de données et d'application. Ce fichier n'entre jamais dans le contrôle de version.
/public/. Les autres répertoires ne doivent jamais être exposés à l'extérieur.
Structure du Répertoire
L'architecture créée au démarrage du projet ; assure une séparation claire des responsabilités (SoC).
bin/ constituent le cœur du framework. La logique métier spécifique au projet n'est pas ajoutée ici. Les classes et les services que vous ajouterez se trouvent sous src/, et les composants d'infrastructure se trouvent sous app/.
Architecture Bootstrapper Critique
ArtiFrame utilise deux bootstrappers complètement indépendants. Cette architecture empêche fondamentalement les problèmes d'en-tête HTML et les failles de sécurité.
Vue ViewControl.php
Utilisé pour les pages HTML (fichiers de vue). Démarre la session, charge ViewMethod.
// public/profil.php — TOUT EN HAUT, avant d'imprimer le HTML
<?php
require_once $_SERVER['DOCUMENT_ROOT']
. '/../app/ViewControl.php';
use Bin\ViewMethod;
?>
<!DOCTYPE html>
...
API ApiControl.php
Utilisé pour les fichiers d'endpoints API. Définit l'en-tête JSON, effectue le contrôle de la méthode HTTP, charge SystemMethod.
// public/api/utilisateur/obtenir.php
<?php
// $allowedMethods DOIT être défini avant require
$allowedMethods = ['GET'];
require_once $_SERVER['DOCUMENT_ROOT']
. '/../app/ApiControl.php';
use Bin\SystemMethod;
Ensemble de Règles Standard
Règle 1 : Architecture data-js Critique
Les événements JavaScript ne peuvent jamais être écoutés via une class ou un id. Ce sont des identités visuelles/de style. Toutes les interactions JS sont gérées par l'attribut data-js. Si CSS supprime une classe, JavaScript ne plante jamais.
<!-- ❌ Anti-Pattern — non pris en charge -->
<button id="submitBtn" class="btn">Envoyer</button>
// JS: document.getElementById('submitBtn').addEventListener(...)
<!-- ✅ Standard ArtiFrame -->
<button class="btn btn-primary" data-js="login-submit">Envoyer</button>
// JS: document.querySelector('[data-js="login-submit"]').addEventListener(...)
Règle 2 : Architecture de Thème
Les modes Sombre/Clair et les thèmes sont gérés via les attributs data-theme et data-mode de la balise <html>. Les classes de corps ne sont pas utilisées.
<!-- Balise d'ouverture HTML provenant du modèle view.stub -->
<html lang="fr" data-theme="default" data-mode="light">
/* Définition du thème dans app.css */
html[data-theme="default"][data-mode="dark"] {
--bg-color: #0b0c0e;
--text-main: #ffffff;
}
html[data-theme="default"][data-mode="light"] {
--bg-color: #ffffff;
--text-main: #111111;
}
Règle 3 : Flux de Données Sécurisé
Toutes les données provenant de la base de données sont enveloppées avec display() avant d'être imprimées sur le DOM. Chaque donnée entrant dans l'API est nettoyée avec sanitizeString() ou sanitizeInt() avant d'être traitée.
Règle 4 : Gestion des Erreurs avec APP_ENV
La valeur APP_ENV dans le fichier .env détermine la visibilité des erreurs. En production, aucun message d'erreur n'est affiché à l'utilisateur.
// config/app-version.php
define('APP_ENV', (int)$_ENV['APP_ENV']); // 1=Debug, 0=Production
if (APP_ENV === 1) {
ini_set('display_errors', 1);
error_reporting(E_ALL);
} else {
ini_set('display_errors', 0);
}
Écosystème CLI
ArtiFrame CLI ouvre un shell interactif lorsque vous tapez artiframe dans le terminal. Toutes les commandes s'exécutent dans ce shell. Les commandes peuvent également être exécutées en une seule fois.
# Mode interactif (recommandé)
artiframe
artiframe> make:view admin/utilisateurs.php
# Mode à usage unique
artiframe make:view admin/utilisateurs.php
new Commande CLI
Crée un nouveau projet ArtiFrame. Génère le squelette complet du répertoire, les fichiers bootstrapper et la première page d'index.
artiframe> new nom-du-projet
Structure créée :
make:view Commande CLI
Crée un nouveau fichier de page (view) et ses ressources CSS/JS dédiées. Les ressources sont automatiquement liées à la page avec une invalidation du cache (cache-busting) via ?v=APP_VERSION.
artiframe> make:view admin/utilisateurs.php
Fichiers créés :
✔ public/admin/utilisateurs.php
✔ public/assets/css/admin/utilisateurs.css
✔ public/assets/js/admin/utilisateurs.js
Le fichier view généré inclut déjà `ViewControl` au début, comprend les inclusions de head/header/footer, et les liens CSS/JS sont connectés avec le système de cache-busting.
make:api Commande CLI
Crée un fichier endpoint API en sélectionnant l'un des deux modèles disponibles. Dans chaque nouveau fichier API, la variable $allowedMethods et l'inclusion de ApiControl.php sont déjà préparées.
standart — API à Action Unique
Pour les endpoints qui effectuent une seule tâche (connexion, envoi, suppression). La logique métier y est écrite directement.
artiframe> make:api standart api/auth/connexion.php
<?php
$allowedMethods = ['POST']; // Accepte uniquement POST
require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/ApiControl.php';
use Bin\SystemMethod;
// Logique métier ici...
jsonResponse(['status' => 'success'], 200);
switch-case — API Multi-Actions
Une structure qui gère les opérations CRUD pour un module dans un seul endpoint. L'opération à effectuer est déterminée par le paramètre action.
artiframe> make:api switch-case api/utilisateur/gerer.php
<?php
$allowedMethods = ['POST'];
require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/ApiControl.php';
use Bin\SystemMethod;
$action = sanitizeString($_POST['action'] ?? '');
switch ($action) {
case 'create':
jsonResponse(['status' => 'success', 'message' => 'Créé.'], 200);
break;
case 'update':
jsonResponse(['status' => 'success', 'message' => 'Mis à jour.'], 200);
break;
case 'delete':
jsonResponse(['status' => 'success', 'message' => 'Supprimé.'], 200);
break;
default:
jsonResponse(['status' => 'error', 'message' => 'Action non valide.'], 400);
}
make:class Commande CLI
Crée un nouveau fichier de classe PHP avec son espace de noms (namespace) et son modèle de classe déjà préparés.
artiframe> make:class src/Service/EmailService.php
Si le répertoire de la classe n'est pas spécifié, la commande renverra une erreur :
artiframe> make:class
❌ Erreur : Le répertoire de la classe doit être spécifié ! (par ex. /app ou /src)
Example: /src/Service/PaymentService
version Commande CLI
Met à jour le numéro de version dans config/app-version.php selon les règles du versionnage sémantique (SemVer). Format de version : MAJOR.MINOR.PATCH
| Commande | Description | Exemple |
|---|---|---|
| version upgrade patch | Correction de bogue, amélioration mineure | 1.2.3 → 1.2.4 |
| version upgrade minor | Nouvelle fonctionnalité rétrocompatible | 1.2.3 → 1.3.0 |
| version upgrade major | Changement majeur (rupture de compatibilité) | 1.2.3 → 2.0.0 |
| version downgrade patch | Annuler le dernier patch | 1.2.4 → 1.2.3 |
| version downgrade minor | Annuler la dernière version mineure | 1.3.0 → 1.2.0 |
| version downgrade major | Annuler la dernière version majeure | 2.0.0 → 1.0.0 |
artiframe> version upgrade minor
✔ La version a été mise à jour de 1.2.0 → 1.3.0.
View Helpers — display() ViewMethod
Applique une protection XSS obligatoire lors de l'impression de données provenant de la base de données ou de la saisie utilisateur sur le DOM. Au lieu de lancer une erreur sur des valeurs nulles ou vides, elle renvoie une valeur par défaut.
string display(mixed $data, string $default = '')$defaultLe deuxième paramètre (
$default) est le texte de secours à afficher lorsque les données provenant de la base de données sont vides (null, false, chaîne vide). Par exemple, si vous utilisez display($nom, 'Anonyme') pour un utilisateur dont le nom n'a pas été saisi, votre page présentera un contenu significatif au lieu de vilains espaces vides.
<!-- ❌ Non sécurisé — crée une vulnérabilité XSS -->
<h1><?= $user['nom'] ?></h1>
<!-- ✅ Utilisation sécurisée d'ArtiFrame -->
<h1><?= display($user['nom'], 'Utilisateur Anonyme') ?></h1>
View Helpers — escapeUrl() ViewMethod
Utilisé lors de l'impression des liens reçus des utilisateurs (par exemple, les sites Web de profil) dans des balises <a href="..."> ou <img src="...">. Il neutralise les charges utiles dangereuses comme javascript:alert(1) (XSS stocké), empêchant l'exécution de code via le lien.
<!-- ❌ Non sécurisé — le code JS peut fuiter via l'URL -->
<a href="<?= $user['website'] ?>">Visiter le Site</a>
<!-- ✅ Utilisation sécurisée d'ArtiFrame -->
<a href="<?= escapeUrl($user['website']) ?>">Visiter le Site</a>
View Helpers — csrfField() ViewMethod
Ajoute un champ de jeton caché aux formulaires HTML pour les protéger contre les attaques CSRF. Son utilisation est obligatoire sur chaque page contenant un formulaire POST.
string csrfField()<form action="/api/sauvegarder.php" method="POST">
<?= csrfField() ?> <!-- Obligatoire pour la sécurité -->
<input type="text" name="nom">
<button type="submit" data-js="save-btn">Sauvegarder</button>
</form>
View Helpers — Fonctions de Date ViewMethod
Traite les chaînes de date au format Y-m-d H:i:s provenant de la base de données ou les valeurs timestamp UNIX. Toutes les sorties textuelles sont localisées selon la langue (tr, en, de, fr, es).
| Fonction | Exemple de Sortie | Description |
|---|---|---|
| day($date) | 24 | Jour uniquement |
| month($date) | 07 | Mois (chiffre) uniquement |
| year($date) | 2026 | Année |
| timeOnly($date) | 14:30 | Heure:Minute |
| fulldate($date) | 24.07.2026 | Date complète |
| formatDate($date, $format) | 24.07.2026 14:30 | Format personnalisé |
| monthName($date, $lang) | Juillet / July / Juli | Nom du mois (selon la langue) |
| fulldateName($date, $lang) | 24 Juillet 2026 / July 24, 2026 | Date complète (avec nom du mois, selon la langue) |
| timeAgo($date, $lang) | il y a 5 minutes / 5 minutes ago | Style réseaux sociaux (selon la langue) |
$format et $lang
$format(Format) : Utilisé uniquement avec la fonctionformatDate(). Accepte les lettres de date standards de PHP. (Par exemple :'d/m/Y'➔ 24/07/2026, ou'H:i'➔ 15:30). Vous permet de créer votre propre modèle de date lorsque les fonctions prêtes à l'emploi (day, year, etc.) sont insuffisantes.$lang(Langue) : Utilisé dans les fonctions dont la sortie contient du texte (nom du mois, mot "il y a"). Si vous laissez ce paramètre vide, le système fonctionne par défaut en'en'(Anglais). Si vous créez un projet multilingue, il vous suffit de saisir le code de langue (tr, en, de, fr, es) dans le deuxième paramètre. (Ex :timeAgo($date, 'fr')➔ il y a 5 minutes)
<!-- Supposons que nous ayons un timestamp UNIX obtenu via time() -->
<?php $date = time(); ?>
<!-- Date complète selon la langue -->
<span><?= fulldateName($date, 'fr') ?></span>
<!-- Sortie : 24 Juillet 2026 -->
<!-- Affichage de l'heure style réseaux sociaux -->
<span><?= timeAgo($date, 'en') ?></span>
<!-- Sortie : 5 minutes ago -->
<span><?= timeAgo($date, 'fr') ?></span>
<!-- Sortie : il y a 5 minutes -->
View Helpers — Formatage de Texte ViewMethod
truncate($text, $length, $append)
string truncate(string $text, int $length = 100, string $append = '...')
Tronque les textes longs (comme les résumés de blog) à la limite de caractères souhaitée sans couper le dernier mot et ajoute le suffixe spécifié à la fin.
<p><?= truncate($article['contenu'], 160, '...') ?></p>
View Helpers — money() ViewMethod
Formate le montant avec le symbole de la devise. Le code de la devise (ISO) détermine automatiquement l'emplacement du symbole. La devise par défaut est usd.
| Code | Sortie | Devise |
|---|---|---|
| usd | $1.250,00 | Dollar Américain |
| eur | 1.250,00 € | Euro |
| try / tl | 1.250,00 ₺ | Livre Turque |
| gbp | £1.250,00 | Livre Sterling |
| jpy | 1.250,00 ¥ | Yen Japonais |
| inr | 1.250,00 ₹ | Roupie Indienne |
| rub | 1.250,00 ₽ | Rouble Russe |
| krw | 1.250,00 ₩ | Won Sud-Coréen |
| brl | R$1.250,00 | Réal Brésilien |
| aed | 1.250,00 د.إ | Dirham des EAU |
<span><?= money($produit['prix'], 'eur') ?></span>
<!-- Sortie : 1.250,00 € -->
<span><?= money($produit['prix'], 'usd') ?></span>
<!-- Sortie : $1.250,00 -->
System Helpers — jsonResponse() SystemMethod
Définit l'en-tête JSON, fournit le code d'état HTTP et imprime la sortie de manière sécurisée avec json_encode, puis termine le script. Toutes les réponses de l'API doivent être données via cette fonction.
void jsonResponse(array $data, int $statusCode = 200)// Réponse réussie
jsonResponse(['status' => 'success', 'data' => $utilisateur], 200);
// Réponse d'erreur
jsonResponse(['status' => 'error', 'message' => 'Accès non autorisé.'], 401);
System Helpers — verifyCsrf() SystemMethod
Vérifie que la requête POST entrante provient d'un formulaire légitime. Renvoie false si csrfField() n'a pas été ajouté au formulaire ou si le jeton n'est pas valide.
if (!verifyCsrf($_POST['csrf_token'] ?? '')) {
jsonResponse(['status' => 'error', 'message' => 'Jeton CSRF invalide.'], 403);
}
System Helpers — Fonctions Sanitize (Nettoyage) SystemMethod
| Fonction | Description |
|---|---|
| sanitizeInt($value) | Supprime toutes les lettres, symboles et virgules, en ne laissant que les chiffres entiers. Utilisé pour les ID ou les limites. |
| sanitizeFloat($value) | Nettoie tout sauf les nombres décimaux. Utilisé pour les montants monétaires ou les métriques. |
| sanitizeString($value) | Pour empêcher les attaques XSS et similaires, détruit toutes les balises HTML et PHP (<script>, <iframe>, etc.). Laisse un texte brut sécurisé. |
| sanitizeEmail($email) | Filtre tous les caractères invalides et dangereux qui ne correspondent pas au format de l'e-mail. |
$id = sanitizeInt($_POST['id'] ?? 0);
$nom = sanitizeString($_POST['nom'] ?? '');
$email = sanitizeEmail($_POST['email'] ?? '');
System Helpers — HTTP & Requête SystemMethod
getIP()
string getIP()
Obtient la véritable adresse IP de l'utilisateur, même derrière Cloudflare ou un Proxy.
getMethod()
string getMethod()
Renvoie la méthode de la requête HTTP active (GET, POST, PUT, DELETE).
System Helpers — Sécurité SystemMethod
generateToken($length)
string generateToken(int $length = 32)
Crée une chaîne hexadécimale cryptographiquement sécurisée. Utilisé pour les réinitialisations de mot de passe ou les jetons d'accès API.
API — Contrôle de Méthode HTTP ApiControl
Les fichiers d'API ArtiFrame n'autorisent aucune requête en dehors du tableau $allowedMethods. Si un pirate tente d'envoyer un POST à une API GET, la demande est bloquée avant même que le fichier ne soit lu, et une erreur HTTP 405 (Method Not Allowed) est renvoyée.
$allowedMethods tout en haut de votre page API (avant require).
API — Politique CORS ApiControl
ArtiFrame est livré configuré par défaut pour n'accepter que les requêtes de la même origine (Same-Origin). Si vous écrivez une API pour une application mobile (ex: React Native) ou un frontend distant, vous pouvez facilement gérer cela avec la variable $enableCors.
<?php
$allowedMethods = ['POST'];
$enableCors = true; // Autorise l'accès de n'importe où
require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/ApiControl.php';
API — Limitation de Débit (Rate Limiting)
La protection contre les requêtes excessives n'est pas encore activée par défaut, mais une architecture qui limite l'adresse IP pour empêcher les requêtes par force brute ou DoS au niveau du contrôleur d'API est en cours de développement (à venir dans la version 1.1).
Flux de Travail Complet
Voyons à quoi ressemble un flux de travail typique dans ArtiFrame. Supposons que nous voulions créer une page de connexion.
-
Créer la page (View)
Ouvrez la CLI et tapez
make:view auth/connexion.php. La page HTML, le fichier CSS et le fichier JS sont générés. -
Écrire l'interface
Dans
public/auth/connexion.php, créez votre balise form. Ajoutez l'actionaction="/api/auth/login.php",method="POST", et placez<?= csrfField() ?>à l'intérieur. Ajoutez la classedata-js="login-btn"à votre bouton d'envoi. -
Créer l'API
Ouvrez la CLI et tapez
make:api standart api/auth/login.php. Dans le fichier créé, assurez-vous que$allowedMethods = ['POST'];est défini. -
Gérer avec JavaScript (Optionnel)
Dans
public/assets/js/auth/connexion.js, écoutez le bouton en utilisant[data-js="login-btn"]. Effectuez la requête AJAX vers l'API. (Si vous n'utilisez pas JS, le formulaire fonctionnera quand même et redirigera classiquement via POST). -
Nettoyer et Répondre
Dans votre fichier API, nettoyez les données POST entrantes :
$email = sanitizeEmail($_POST['email']);. Interrogez la base de données. Si la vérification du mot de passe réussit, démarrez la session utilisateur et renvoyez le succès avecjsonResponse().