8768 sujets

Développement web côté serveur, CMS

Pages :
Modérateur
(reprise du message précédent)

Lis et teste ce bout de code :


<?php

function slugify($text, string $divider = '-'){
    $text = preg_replace('~[^\pL\d]+~u', $divider, $text);
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    $text = preg_replace('~[^-\w]+~', '', $text);
    $text = trim($text, $divider);
    $text = preg_replace('~-+~', $divider, $text);
    $text = strtolower($text);

    if (empty($text)) {
        return 'n-a';
    }

    return $text;
}
if(!empty($_POST)){
    // nettoie les données du formulaire
    $clean_methods = [
        'trim',
        'strip_tags',
        'htmlspecialchars',
    ];
    foreach($clean_methods as $method){
        $_POST = array_map($method, $_POST);
    }

    // validation
    $_POST['errors'] = [];
    foreach($_POST as $key => $value){
        switch($key){
            case 'email':
                if(empty($value)){
                    $_POST['errors'][$key] = "Ne doit pas être vide";
                }else if(!filter_var($value, FILTER_VALIDATE_EMAIL)){
                    $_POST['errors'][$key] = "l'email ne semble pas valide";
                }
                break;
            case 'message':
                $words = file('./interdictions.txt');
                $value_slugified = slugify($value);
                if(empty($value)){
                    $_POST['errors'][$key] = "Ne doit pas être vide";
                }else{
                    $words_slugified = array_map('slugify', $words);
                    $pattern = sprintf('#\b(%s)\b#', implode('|', $words_slugified));
                    if(preg_match($pattern, $value_slugified, $word)){
                        $_POST['errors'][$key] = sprintf("Le mot <strong>%s</strong> est interdit, veuillez ne pas utiliser l'écriture inclusive", current($word));
                    }
                }
                break;
        }
    }

    if(empty($_POST['errors'])){
        // envoyer email
    }
}


?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.8.1/dist/css/foundation-float.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.8.1/dist/css/foundation-prototype.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.8.1/dist/css/foundation-rtl.min.css" crossorigin="anonymous">
        <style>
            .grid-container{
                max-width:50rem;
            }
            input[type=text], textarea{
                margin: 0;
            }
            .input{
                margin-top: 1rem;
            }
            span.error{
                color: red;
            }
        </style>
    </head>
    <body>
        <main class="grid-container margin-vertical-3">
            <form method="post">
                <div class="input text">
                    <label>
                        <span>email</span>
                        <input type="text" name="email" value="<?= !empty($_POST['email']) ? $_POST['email'] : ''?>">
                    </label>
                    <?php if(!empty($_POST['errors']['email'] )): ?>
                    <span class="error"><?= $_POST['errors']['email']  ?></span>
                    <?php endif ?>
                </div>
                <div class="input textarea">
                    <label>
                        <span>message</span>
                        <textarea name="message"><?= !empty($_POST['message']) ? $_POST['message'] : ''?></textarea>
                    </label>
                    <?php if(!empty($_POST['errors']['message'] )): ?>
                    <span class="error"><?= $_POST['errors']['message'] ?></span>
                    <?php endif ?>
                </div>
                <div class="input submit">
                    <button class="button" type="submit">envoyer</button>
                </div>
            </form>
        </main>
    </body>
</html>

Modifié par niuxe (11 Jan 2024 - 09:36)
Merci, je vais prendre un peu de temps et voir ton script.
À le lire, je suppose qu'il remplace, d'un seul coup, tout ce qui est sur le mien. Le choix des mots interdits, la validation php du formulaire, la sécurité avec 'trim', 'strip_tags', et 'htmlspecialchars'.
Modérateur
J'ai identifié pas mal de petites choses :
- pas de filtrage des données entrantes
- pas de validation correcte du formulaire

Tu n'as plus besoin depuis des lustres de faire une regex pour valider une adresse mail. filter_var() est une fonction bien utile en php.

Pour l'interdiction des mots, il faut que tes données soient équivalentes de part et d'autres. Je ne dis pas que ma version est impec. Cependant, elle me semble plus efficace. Le meilleur moyen est de "slugifier". À noter que le slug permet en général de formater correctement une url (route).

Aussi, tu peux éviter le array_map() des mots venant de ton fichier (interdictions.txt) si tu réécris ton fichier en amont. Tu gagneras automatiquement en perf puisque les mots de ton fichier seront déjà formatés. Mais il faut penser qu'à chaque fois, tu édites ce fichier, il faut le régénérer.
Modifié par niuxe (11 Jan 2024 - 15:11)
Je vais voir tout ça, mais doucement, ça fait pas mal pour mon niveau en php. Surtout, le formulaire est en ligne, chaque fois que j'engage une modification, je dois être prudent, comme avec ce qui vient de se passer. Et je n'ai pas de serveur local pour tester.
En attendant, je vais mettre pour avis le site sur lequel est ce formulaire qui m'a causé des soucis. J'ai besoin de retours.
niuxe a écrit :

Aussi, tu peux éviter le array_map() des mots venant de ton fichier (interdictions.txt) si tu réécris ton fichier en amont. Tu gagneras automatiquement en perf puisque les mots de ton fichier seront déjà formatés. Mais il faut penser qu'à chaque fois, tu édites ce fichier, il faut le régénérer.


Qu'entends-tu par régénérer un fichier texte comme celui interdictions.txt ?
Modifié par Bongota (11 Jan 2024 - 17:14)
Modérateur
Bongota a écrit :


Qu'entends-tu par régénérer un fichier texte comme celui interdictions.txt ?


Comme tu as pu le constater, il y a dans la validation du formulaire, il y a un array_map(). Ce array_map() a un cout en termes de performance (surement plus rapide qu'une boucle). Si ton fichier fait un million de lignes, la réponse au client sera automatiquement plus lente.
Si lorsque tu édites ton fichier 'interdictions.txt', tu sauvegardes celui-ci et que tu le régénères avec la fonction 'slugify', tu seras plus performant lors de la soumission du formulaire.

À noter que si ton fichier ne fait que quelques lignes, je pense que ça ne vaut pas le coup de faire cette manip.
Modifié par niuxe (12 Jan 2024 - 18:57)
Oui, sans doutes. Ce fichier ne sera jamais très très long.
Au sujet des mot séparés que tu as vu l'autre jour, il s'agissait d'un accident avec ma souris qui a déposé le contenu du tampon sur la page, sans que je ne m'en rende compte.