diff --git a/public/servercheck.php b/public/servercheck.php
new file mode 100644
index 0000000..1e63dc6
--- /dev/null
+++ b/public/servercheck.php
@@ -0,0 +1,412 @@
+=');
+
+// Extensions requises : [nom => optionnel?]
+$extensions = [
+ 'pdo' => false,
+ 'pdo_mysql' => false,
+ 'mbstring' => false,
+ 'openssl' => false,
+ 'tokenizer' => false,
+ 'xml' => false,
+ 'ctype' => false,
+ 'json' => false,
+ 'bcmath' => false,
+ 'fileinfo' => false,
+ 'zip' => false,
+ 'pdo_pgsql' => true, // optionnel : seulement si PostgreSQL
+ 'curl' => true, // optionnel : mises à jour automatiques
+ 'intl' => true, // optionnel : formatage avancé des dates
+];
+
+// Répertoires à vérifier en écriture
+$dirs = [
+ 'storage/' => $root . '/storage',
+ 'storage/logs/' => $root . '/storage/logs',
+ 'storage/app/' => $root . '/storage/app',
+ 'storage/framework/' => $root . '/storage/framework',
+ 'bootstrap/cache/' => $root . '/bootstrap/cache',
+ 'Racine (écriture .env)' => $root,
+];
+
+// Fichiers à vérifier
+$files = [
+ '.env' => [$root . '/.env', false],
+ 'vendor/autoload.php' => [$root . '/vendor/autoload.php', false],
+ 'storage/installed' => [$root . '/storage/installed', true],
+ 'public/build/manifest.json' => [$root . '/public/build/manifest.json', false],
+];
+
+// Configuration PHP recommandée : [directive => [valeur_min_bytes, label_min]]
+$iniChecks = [
+ 'memory_limit' => [128 * 1024 * 1024, '128 Mo'],
+ 'upload_max_filesize'=> [2 * 1024 * 1024, '2 Mo'],
+ 'post_max_size' => [8 * 1024 * 1024, '8 Mo'],
+ 'max_execution_time' => [30, '30 s'],
+];
+
+function iniBytes(string $val): int {
+ $val = trim($val);
+ $last = strtolower($val[-1] ?? '');
+ $n = (int) $val;
+ return match ($last) {
+ 'g' => $n * 1024 * 1024 * 1024,
+ 'm' => $n * 1024 * 1024,
+ 'k' => $n * 1024,
+ default => $n,
+ };
+}
+
+// Test de connexion BDD (si formulaire soumis)
+$dbResult = null;
+if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['db_host'])) {
+ $driver = $_POST['db_driver'] ?? 'mysql';
+ $host = $_POST['db_host'] ?? '';
+ $port = (int) ($_POST['db_port'] ?? ($driver === 'pgsql' ? 5432 : 3306));
+ $dbname = $_POST['db_name'] ?? '';
+ $user = $_POST['db_user'] ?? '';
+ $password = $_POST['db_password'] ?? '';
+ try {
+ $dsn = $driver === 'pgsql'
+ ? "pgsql:host={$host};port={$port};dbname={$dbname}"
+ : "mysql:host={$host};port={$port};dbname={$dbname};charset=utf8mb4";
+ $pdo = new PDO($dsn, $user, $password, [PDO::ATTR_TIMEOUT => 5]);
+ $ver = $pdo->query('SELECT version()')->fetchColumn();
+ $dbResult = ['ok' => true, 'msg' => "Connexion réussie — " . htmlspecialchars($ver)];
+ } catch (Exception $e) {
+ $dbResult = ['ok' => false, 'msg' => htmlspecialchars($e->getMessage())];
+ }
+}
+
+// ── Compteur global ────────────────────────────────────────────────────────
+$totalChecks = 0;
+$totalFailed = 0;
+
+?>
+
+
+
+
+Diagnostic serveur — MesRelevés
+
+
+
+
+
+
Diagnostic serveur — MesRelevés
+
Version PHP = htmlspecialchars($phpVer) ?> · = htmlspecialchars($_SERVER['SERVER_SOFTWARE'] ?? 'Serveur inconnu') ?>
+
+
+
+ FICHIER DE TEST UNIQUEMENT — À supprimer immédiatement après diagnostic. Ne jamais laisser en production.
+
+
+ $optional) {
+ if (!extension_loaded($ext) && !$optional) $extMandatoryFailed++;
+}
+$dirFailed = 0;
+foreach ($dirs as $path) {
+ if (!is_writable($path)) $dirFailed++;
+}
+$fileFailed = 0;
+foreach ($files as [$path, $optional]) {
+ if (!file_exists($path) && !$optional) $fileFailed++;
+}
+$totalFailed = (!$phpOk ? 1 : 0) + $extMandatoryFailed + $dirFailed + $fileFailed;
+$totalOk = ($phpOk ? 1 : 0)
+ + count(array_filter(array_keys($extensions), fn($e) => extension_loaded($e) && !$extensions[$e]))
+ + count(array_filter(array_keys($dirs), fn($k) => is_writable($dirs[$k])))
+ + count(array_filter(array_keys($files), fn($k) => file_exists($files[$k][0])));
+?>
+
+
+
+
= $totalFailed === 0 ? '✓' : $totalFailed ?>
+
= $totalFailed === 0 ? 'Tout est OK' : 'Problème(s) bloquant(s)' ?>
+
+
+
= PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION ?>
+
Version PHP
+
+
+
= count(array_filter(array_keys($extensions), fn($e) => extension_loaded($e))) ?>/= count($extensions) ?>
+
Extensions chargées
+
+
+
= ini_get('memory_limit') ?>
+
memory_limit
+
+
+
+ {{-- ── Informations serveur ────────────────────────────────────────────── --}}
+
+
+
+ - Serveur
- = htmlspecialchars($_SERVER['SERVER_SOFTWARE'] ?? '—') ?>
+ - SAPI
- = htmlspecialchars(php_sapi_name()) ?>
+ - Document root
- = htmlspecialchars($_SERVER['DOCUMENT_ROOT'] ?? '—') ?>
+ - Chemin du script
- = htmlspecialchars(__FILE__) ?>
+ - Racine projet
- = htmlspecialchars($root) ?>
+ - OS
- = htmlspecialchars(PHP_OS_FAMILY) ?>
+ - Fuseau horaire
- = htmlspecialchars(ini_get('date.timezone') ?: 'non défini') ?>
+
+
+
+ {{-- ── Version PHP ─────────────────────────────────────────────────────── --}}
+
+
+
+
+ | PHP = htmlspecialchars($phpVer) ?> |
+ Minimum requis : = $reqVer ?> |
+ = $phpOk ? '✓ OK' : '✗ Insuffisant' ?> |
+
+
+
+
+ {{-- ── Extensions PHP ──────────────────────────────────────────────────── --}}
+
+
+
+ | Extension | Statut | Note |
+
+ $optional):
+ $loaded = extension_loaded($ext); ?>
+
+ | = htmlspecialchars($ext) ?> |
+
+
+ ✓ Présente
+
+ ⚠ Absente
+
+ ✗ Manquante
+
+ |
+
+
+
+
+
+ |
+
+
+
+
+
+
+ {{-- ── Configuration PHP ───────────────────────────────────────────────── --}}
+
+
+
+ | Directive | Valeur actuelle | Minimum recommandé | Statut |
+
+ [$minBytes, $minLabel]):
+ $raw = ini_get($key);
+ $bytes = iniBytes($raw);
+ $ok = $bytes >= $minBytes || $minBytes === 30 && ($bytes === 0 || $bytes >= $minBytes);
+ // max_execution_time = 0 means unlimited
+ if ($key === 'max_execution_time') $ok = ($bytes === 0 || $bytes >= $minBytes);
+ ?>
+
+ | = htmlspecialchars($key) ?> |
+ = htmlspecialchars($raw) ?> |
+ = $minLabel ?> |
+ = $ok ? '✓ OK' : '⚠ Faible' ?> |
+
+
+
+
+
+
+ {{-- ── Répertoires ─────────────────────────────────────────────────────── --}}
+
+
+
+ | Répertoire | Chemin | Statut |
+
+ $path):
+ $exists = is_dir($path);
+ $writable = $exists && is_writable($path);
+ ?>
+
+ | = htmlspecialchars($label) ?> |
+ = htmlspecialchars(str_replace($root, '…', $path)) ?> |
+
+
+ ✗ Inexistant
+
+ ✓ OK
+
+ ✗ Non accessible
+
+ |
+
+
+
+
+
+
+ {{-- ── Fichiers clés ───────────────────────────────────────────────────── --}}
+
+
+
+ | Fichier | Présent | Note |
+
+ [$path, $optional]):
+ $exists = file_exists($path); ?>
+
+ | = htmlspecialchars($label) ?> |
+
+
+ ✓ Présent
+
+ — Absent
+
+ ✗ Manquant
+
+ |
+
+
+
+
+
+ |
+
+
+
+
+
+
+ {{-- ── Test de connexion BDD ───────────────────────────────────────────── --}}
+
+
+
+ Généré le = date('d/m/Y à H:i:s') ?> · MesRelevés = htmlspecialchars(trim(@file_get_contents($root . '/VERSION') ?: '')) ?>
+
+
+
+
+