Files
api-php-yt-videos/README.md
T

4.4 KiB

api-tube

API REST en PHP natif (POO) pour gérer des liens de vidéos YouTube.

  • PHP natif uniquement : aucun framework, aucune dépendance, aucun Composer
  • Stockage SQLite via PDO

Prérequis

  • PHP >= 8.1 avec l'extension pdo_sqlite

Activer l'extension si absente (Debian/Ubuntu) :

sudo apt install php8.5-sqlite3
php -m | grep -i sqlite   # doit afficher pdo_sqlite et/ou sqlite3

Lancement

php -S localhost:8000 -t public

La base database/api_tube.sqlite et son schéma sont créés automatiquement au premier appel (via les migrations).

Migrations

Les migrations sont des fichiers SQL numérotés dans database/migrations/, appliqués une seule fois et tracés dans la table migrations.

Elles sont exécutées automatiquement à la connexion à la base. Pour les appliquer manuellement (hors serveur web) :

php database/migrate.php

Ajouter une migration :

# fichier database/migrations/002_ajout_colonne.sql
echo "ALTER TABLE links ADD COLUMN visible INTEGER DEFAULT 1;" > database/migrations/002_ajout_colonne.sql
php database/migrate.php

Endpoints

Méthode Route Description Codes retour
GET /links Lister tous les liens 200
GET /links/{id} Lire un lien 200 / 404
POST /links Créer un lien 201 / 409 / 422
PUT /links/{id} Modifier un lien 200 / 404 / 409 / 422
DELETE /links/{id} Supprimer un lien 204 / 404

Corps attendu (POST / PUT, JSON)

{
  "title": "Titre de la vidéo",
  "description": "Description",
  "link_url": "https://youtube.com/watch?v=VIDEO_ID",
  "thumbnail": "https://img.youtube.com/vi/VIDEO_ID/hqdefault.jpg"
}

title et link_url sont obligatoires ; description et thumbnail sont optionnels. link_url doit être une URL valide et unique.

Tests manuels

bash tests/curl.sh

Sécurité

Éléments de sécurité implémentés dans l'API :

  • Injection SQL : toutes les requêtes avec paramètres utilisent des requêtes préparées PDO (prepare() + execute()) dans src/LinkRepository.php, jamais de concaténation de variables dans le SQL.
  • Validation des entrées : champs obligatoires vérifiés, trim() systématique, et validation de link_url via FILTER_VALIDATE_URL (src/LinkController.php).
  • Pas de fuite d'informations : toute erreur (base, rendu) renvoie une réponse 500 générique Erreur interne du serveur. sans stack trace ni détail (public/index.php). display_errors n'est pas activé.
  • Exposition minimale au web : le DocumentRoot Apache (Docker) pointe vers public/ uniquement ; src/, database/ et la base SQLite ne sont pas servis publiquement. Le .htaccess réécrit toute requête vers index.php.
  • CORS restreint : méthodes limitées à GET, POST, PUT, DELETE, OPTIONS et en-têtes à Content-Type (public/index.php).
  • Base hors de l'image Docker : *.sqlite est exclu via .dockerignore et stocké dans le volume db-data, pas dans les layers de l'image.
  • Typage strict : declare(strict_types=1) dans tous les fichiers PHP, paramètres et retours typés.

Docker

Lancement

docker compose up -d --build
# API accessible sur http://localhost:8000

Arrêter

docker compose down          # conserve la base (volume)
docker compose down -v       # supprime la base (reset complet)

Persistance

La base SQLite est stockée dans le Docker volume db-data : elle survit aux down/up successifs. Un down -v la supprime ; le prochain démarrage recrée la base via les migrations.

Rebuild après modification du code

docker compose up -d --build

Arborescence

public/
  index.php          # point d'entrée unique
  .htaccess          # réécriture vers index.php
src/
  Database.php       # connexion PDO SQLite + exécution des migrations
  LinkRepository.php # CRUD SQL
  LinkController.php # routage, validation, orchestration
database/
  migrate.php        # runner de migrations (CLI)
  migrations/        # fichiers SQL versionnés
Dockerfile           # image PHP 8.4 Apache + mod_rewrite
docker-compose.yml   # service web + volume db-data
.dockerignore