$payload */ public function __construct(public readonly int $statusCode, public readonly array $payload) { parent::__construct($payload['error'] ?? 'error'); } } /** * Raccourci pour interrompre rapidement le traitement avec une erreur typée. * * @param array $extra champs additionnels à inclure dans le payload JSON */ function api_abort(int $status, string $error, ?string $message = null, array $extra = []): never { $payload = ['error' => $error]; if ($message !== null) { $payload['message'] = $message; } if ($extra !== []) { $payload += $extra; } throw new ApiException($status, $payload); } // ----------------------------------------------------------------------------- // Chargement minimal d'un fichier .env (pour le dev local sous Laragon). // En prod docker, c'est `env_file:` qui pousse les variables — on ne fait rien. // ----------------------------------------------------------------------------- $envFile = dirname(__DIR__) . '/.env'; if (is_file($envFile)) { foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) { $line = trim($line); if ($line === '' || $line[0] === '#' || !str_contains($line, '=')) { continue; } [$k, $v] = explode('=', $line, 2); $k = trim($k); $v = trim($v); // Strip guillemets simples ou doubles s'ils encadrent la valeur. if (strlen($v) >= 2 && ( ($v[0] === '"' && substr($v, -1) === '"') || ($v[0] === "'" && substr($v, -1) === "'") )) { $v = substr($v, 1, -1); } // Ne pas écraser un env déjà défini (ex: par docker, par le shell de CI...) if (getenv($k) === false) { putenv("$k=$v"); $_ENV[$k] = $v; } } } // ----------------------------------------------------------------------------- // Autoload PSR-4 pour le namespace Infolab\ -> src/ // On évite Composer : pas de dépendance externe, pas de `composer install`. // ----------------------------------------------------------------------------- spl_autoload_register(static function (string $class): void { $prefix = 'Infolab\\'; if (!str_starts_with($class, $prefix)) { return; } $relative = substr($class, strlen($prefix)); $path = __DIR__ . '/' . str_replace('\\', '/', $relative) . '.php'; if (is_file($path)) { require $path; } }); // ----------------------------------------------------------------------------- // Convertit les warnings/notices PHP en exceptions (sauf ceux supprimés par @). // Centralise tout le tracking d'erreurs dans le handler de index.php. // ----------------------------------------------------------------------------- set_error_handler(static function (int $severity, string $message, string $file, int $line): bool { if (!(error_reporting() & $severity)) { return false; } throw new \ErrorException($message, 0, $severity, $file, $line); });