Les Formulaires en PHP

Maîtrisez la création et le traitement des formulaires en PHP pour interagir avec vos utilisateurs de manière sécurisée.

Introduction aux formulaires

Les formulaires sont essentiels pour interagir avec les utilisateurs d'un site web. Ils permettent de recueillir des données, des commentaires, d'inscrire des utilisateurs et bien plus encore.

En PHP, nous avons deux étapes principales pour travailler avec les formulaires :

  1. Création du formulaire HTML avec des balises <form>, <input>, <select>, etc.
  2. Traitement des données envoyées par l'utilisateur à l'aide de PHP.

Note : La sécurité est primordiale lorsqu'on manipule des données de formulaire. Toujours valider et nettoyer les entrées des utilisateurs pour éviter des failles comme les injections SQL ou les attaques XSS.

Création d'un formulaire HTML

Un formulaire HTML est défini par la balise <form> avec des attributs importants comme method (GET ou POST) et action (où envoyer les données).

Structure de base d'un formulaire
<form method="post" action="traitement.php">
    <div class="form-group">
        <label for="nom">Nom</label>
        <input type="text" id="nom" name="nom" required>
    </div>

    <div class="form-group">
        <label for="email">Email</label>
        <input type="email" id="email" name="email" required>
    </div>

    <button type="submit">Envoyer</button>
</form>

Les principaux types de champs

Méthodes GET et POST

Les deux méthodes principales pour envoyer des données de formulaires sont GET et POST :

Méthode GET
  • Les données sont ajoutées à l'URL
  • Format : page.php?param1=valeur1¶m2=valeur2
  • Limité en taille (environ 2048 caractères)
  • Visible dans l'historique du navigateur
  • Utile pour les recherches et les filtres
  • Non recommandé pour les données sensibles
  • Accessible via $_GET en PHP
<form method="get" action="search.php">
    <input type="search" name="q">
    <button type="submit">Rechercher</button>
</form>
Méthode POST
  • Les données sont envoyées dans le corps de la requête
  • Pas visible dans l'URL
  • Pas de limite de taille pratique
  • Non visible dans l'historique du navigateur
  • Idéal pour les formulaires d'inscription/connexion
  • Recommandé pour les données sensibles
  • Accessible via $_POST en PHP
<form method="post" action="login.php">
    <input type="text" name="username">
    <input type="password" name="password">
    <button type="submit">Connexion</button>
</form>

Récupération des données en PHP

PHP fournit plusieurs variables superglobales pour accéder aux données des formulaires :

$_GET

Pour récupérer les données envoyées via méthode GET :

<?php
// Vérifier si le paramètre existe
if (isset($_GET['q'])) {
    $recherche = htmlspecialchars($_GET['q']);
    echo "Vous avez recherché : " . $recherche;
}
?>
$_POST

Pour récupérer les données envoyées via méthode POST :

<?php
// Vérifier si le formulaire a été soumis
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = isset($_POST['username']) ? htmlspecialchars($_POST['username']) : '';
    $password = isset($_POST['password']) ? $_POST['password'] : '';
    
    // Traitement du login...
}
?>
$_REQUEST

Contient les données de $_GET, $_POST et $_COOKIE combinées :

<?php
// Récupère la valeur indépendamment de la méthode utilisée
$valeur = isset($_REQUEST['param']) ? htmlspecialchars($_REQUEST['param']) : '';

// Pas recommandé pour le code de production car moins explicite
?>

Validation et sécurisation des données

La validation des données est essentielle pour assurer la sécurité et la fiabilité de votre application.

Validation basique
<?php
// Vérification que les champs requis sont remplis
$errors = [];

if (empty($_POST['email'])) {
    $errors[] = "L'email est obligatoire";
} elseif (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    $errors[] = "Format d'email invalide";
}

if (empty($_POST['password'])) {
    $errors[] = "Le mot de passe est obligatoire";
} elseif (strlen($_POST['password']) < 8) {
    $errors[] = "Le mot de passe doit contenir au moins 8 caractères";
}

if (!empty($errors)) {
    // Affichage des erreurs
    foreach ($errors as $error) {
        echo "
$error
"
; } } else { // Traitement du formulaire valide } ?>
Protection contre les attaques XSS
<?php
// Échappement des données avant affichage
$nom = htmlspecialchars($_POST['nom']);

// Alternative avec filter_var
$commentaire = filter_var(
    $_POST['commentaire'], 
    FILTER_SANITIZE_SPECIAL_CHARS
);

echo "Bonjour, " . $nom . "!";
?>

Attention : Ne faites jamais confiance aux données des utilisateurs. Validez et nettoyez toujours les entrées avant de les utiliser dans votre application.

Upload de fichiers

PHP permet également de gérer les téléchargements de fichiers à l'aide de la superglobale $_FILES.

Formulaire d'upload de fichiers
<form method="post" enctype="multipart/form-data" action="upload.php">
    <div class="form-group">
        <label for="fichier">Sélectionner un fichier</label>
        <input type="file" id="fichier" name="fichier">
    </div>
    <button type="submit">Envoyer</button>
</form>

Traitement côté serveur :

<?php
if (isset($_FILES['fichier'])) {
    $tmpName = $_FILES['fichier']['tmp_name'];
    $name = $_FILES['fichier']['name'];
    $size = $_FILES['fichier']['size'];
    $error = $_FILES['fichier']['error'];
    $type = $_FILES['fichier']['type'];
    
    // Vérification des erreurs
    if ($error === UPLOAD_ERR_OK) {
        // Vérification du type de fichier
        // Déplacement du fichier vers un dossier de destination
        $destination = 'uploads/' . $name;
        if (move_uploaded_file($tmpName, $destination)) {
            echo "Le fichier a été téléchargé avec succès.";
        } else {
            echo "Erreur lors du déplacement du fichier.";
        }
    } else {
        echo "Erreur lors du téléchargement du fichier.";
    }
}
?>

Conseil : Limitez la taille et les types de fichiers acceptés. Utilisez mime_content_type() pour vérifier le type réel du fichier.

Exemple complet de formulaire

Voici un exemple de formulaire de contact complet avec validation et traitement des données :

Formulaire de contact

Code du formulaire
<?php
$formSubmitted = false;
$formErrors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit_demo'])) {
    $formSubmitted = true;
    
    // Récupération et validation
    $nom = isset($_POST['nom']) ? trim($_POST['nom']) : '';
    $email = isset($_POST['email']) ? trim($_POST['email']) : '';
    $age = isset($_POST['age']) ? (int)$_POST['age'] : 0;
    $message = isset($_POST['message']) ? trim($_POST['message']) : '';
    
    // Validation basique
    if (empty($nom)) {
        $formErrors['nom'] = 'Le nom est obligatoire';
    }
    
    if (empty($email)) {
        $formErrors['email'] = 'L\'email est obligatoire';
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $formErrors['email'] = 'Format d\'email invalide';
    }
    
    if ($age < 18) {
        $formErrors['age'] = 'Vous devez avoir au moins 18 ans';
    }
    
    if (empty($message)) {
        $formErrors['message'] = 'Le message est obligatoire';
    }
}
?>

Bonnes pratiques :

  • Affichez les messages d'erreur à côté des champs correspondants
  • Conservez les valeurs déjà saisies en cas d'erreur
  • Utilisez des types de champs appropriés (email, number, etc.)
  • Validez les données côté serveur, même si une validation côté client est en place

Bonnes pratiques de sécurité

Protection CSRF basique
<?php
// Génération d'un jeton CSRF dans la session
session_start();
if (!isset($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf_token = $_SESSION['csrf_token'];
?>

<form method="post">
    <!-- Champ caché pour le jeton CSRF -->
    <input type="hidden" name="csrf_token" value="<?php echo $csrf_token; ?>">
    <!-- Autres champs du formulaire -->
</form>

<?php
// Vérification du jeton CSRF lors de la soumission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!isset($_POST['csrf_token'])) {
        die('Jeton CSRF manquant!');
    }
    
    if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        die('Validation CSRF échouée!');
    }
    
    // Le jeton est valide, traiter le formulaire
}
?>