true, 'cookie_samesite'=>'Strict', 'use_strict_mode'=>true]); header('X-Content-Type-Options: nosniff'); header('Cache-Control: no-store'); $_SESSION['csrf'] ??= bin2hex(random_bytes(32)); function e(string $value): string { return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); } $error = ''; $rows = []; try { $pdo = new PDO((string)getenv('DEMO_DB_DSN'), (string)getenv('DEMO_DB_USER'), (string)getenv('DEMO_DB_PASS'), [PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES=>false]); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $token = is_string($_POST['csrf'] ?? null) ? $_POST['csrf'] : ''; if (!hash_equals($_SESSION['csrf'], $token)) { http_response_code(403); exit('Reload the form.'); } $name = is_string($_POST['name'] ?? null) ? trim($_POST['name']) : ''; $email = is_string($_POST['email'] ?? null) ? trim($_POST['email']) : ''; if ($name === '' || strlen($name) > 80 || strlen($email) > 150 || !filter_var($email, FILTER_VALIDATE_EMAIL)) { $error = 'Enter a name up to 80 bytes and a valid email up to 150 bytes.'; } else { $statement = $pdo->prepare('INSERT INTO contacts (name, email) VALUES (?, ?)'); $statement->execute([$name, $email]); header('Location: contact-demo.php', true, 303); exit; } } $rows = $pdo->query('SELECT name, email FROM contacts ORDER BY id DESC LIMIT 20')->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $exception) { error_log('Local contact demo database operation failed.'); $error = 'Check the local database setup. The contact could not be loaded or saved.'; } ?> Local contact exercise

Local contact exercise

Use made-up details in this local test database.

Latest contacts