Forum Programmation.php [résolu] PHP7.3 et Mariadb - Gestion des erreurs de longueur des champs texte

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
2
15
jan.
2021

Bonjour à tous,

Preambule : Je ne suis pas développeur php.
Je rencontre un soucis avec une vieille appli php5.quelquechose, que je n'ai pas créé, mais que l'on m'a forcé j'ai du adapter pour mettre à jour en php7.0

J'ai donc transformé correctement (je crois) toutes les requêtes en PDO et dans un bloc try/catch, pas trop regardé le reste du code qui est illisible et mal fait … j'ai juste debogué et corrigé les messages d'Erreurs et Notices PHP puis le serveur a été MAJ en debian stretch donc php7.0 et jusqu'ici tout allait bien.

Dernièrement une mise à jour en debian buster (php7.3) et je rencontre ce problème :

SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column XXX
En effet, dans la base de données, un champ texte est en varchar(120), mais dans le formulaire rien ne limite ce champ.
Jusqu'ici, le champ était tronqué sans que ça lève une exception dans php (et sans que les utilisateurs s'en émeuvent).

        $note = isset($_POST['note']) ? secure_input($_POST['note']):'';   // note dans formulaire

[…]

                $q=$pdo->prepare($sql);
                try {$q->execute(array(
                            'note'=>$note,
                            ) 

[…]

1ere question : est-ce normal avec le passage à php7.3 ? Je n'ai rien vu à ce sujet.
2eme question : Quelle est la "bonne" façon de faire pour : soit signaler à l'utilisateur que le texte est trop long, soit le tronquer avant préparation de la requête SQL ?

  • # php.net est ton ami

    Posté par  (site Web personnel) . Évalué à 3 (+2/-0).

    Salut,
    Je ne saurais répondre à la première question.

    Pour la seconde, il n'y a pas de "bonne" façon de faire : à toi de voir … où à ton chef de projet.
    Première option, plus longue en temps mais probablement la plus satisfaisante pour l'utilisateur : il faut contrôler la longueur du champ et en cas de dépassement, afficher un message d'erreur et revenir à la saisie.
    Seconde option, l'utilisateur ne se rend compte de rien : il suffit de faire un $monChamp = substr($monChamp, 0, 120) , et le tour est joué !

    Pour info, toutes les fonctions pour les chaînes de caractères sont dans la doc.

    Bon débogage !

    • [^] # Re: php.net est ton ami

      Posté par  . Évalué à 1 (+0/-0).

      Autre option modifier le champ de la base de données … un varchar(120) ??? pousse un peu plus les murs … au pire reporte la faute sur l'infra et les admin BDD :-)

      Quoi c'est 'dredi j'ai le droit !

      eric.linuxfr@sud-ouest.org

  • # pas sa faute…

    Posté par  . Évalué à 2 (+1/-0).

    Tout d'abord, les versions successives sont devenues de plus en plus strictes (c'est plus pro d'être moins laxiste.) Donc des choses qui passaient inaperçues avant remontent au fur et à mesure qu'on avance dans les versions (des « notices » qui deviennent des « warning » par exemple.) Du coup, il est possible que l'erreur existait déjà mais ne remontait ; même si je pense que le souci ne soit pas à ce niveau. Il est possible aussi que si ça remontait on ne l'ai jamais vu jusqu'à ce que tu captures les erreurs…
    Je soupçonne que ce soit plausiblement une amélioration du pilote (PDO-MySQL) qui du coup n'est plus silencieux sur ce genre de notification. Il est possible aussi que ça vienne du gestionnaire de bases de données : soit une évolution de version (avec de nouveaux paramètres), soit juste un changement des paramètres existants, dans les deux cas on a maintenant un avertissement là où on avait une troncature silencieuse.

    Si on reste sur cent-vingts caractères (mais ceci s'applique pour n'importe quelle longueur en fait) il faut déjà au niveau du formulaire le mentionner pour que les usagers n'aient pas de surprise.

    <input type=text name=note maxlength=120 />

    Les navigateurs pouvant ne pas respecter ou des esprits malins pouvant soumettre leur propre formulaire, il faut en plus :

    • soit ajouter dans l'explication du champ cette limitation (et là on peut se dispenser des traitements suivants et enregistrer directement la valeur tronquée –comme indiqué dans une autre réponse)
    • soit vérifier au niveau serveur et traiter le dépasser de l'une (ou) des façons suivantes :
      • remonter que l'enregistrement a été tronquée
      • ou lever une erreur et inviter à la correction
    • soit autre chose que je ne vois pas tout de suite
  • # Le "fautif" est MySQL et pas PHP

    Posté par  (site Web personnel) . Évalué à 5 (+4/-0).

    Bonjour,

    Vu que tu as fait une mise à jour du système il y a de grandes chances que ton serveur MySQL y soit aussi passé.
    Il y a eu une modification au passage à MySQL 5.7 : passage au mode strict par défaut

    https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

    C'est typiquement le genre d'erreurs qui autrefois étaient silencieusement mise sous le tapis, MySQL tronquait sans vergogne ta chaîne de caractère et pas de retour en erreur.

    Maintenant ce n'est plus le cas et tant mieux.

    Charge donc à toi de valider ou transformer les données avant insertion dans la base de données.

    Pour la validation en PHP je ne saurai trop te conseiller de jeter un œil du côté du composant Validator de Symfony : https://symfony.com/doc/current/validation.html. Il te permettra assez facilement de valider toutes les données saisies avant leur validation et de remonter les erreurs à l'utilisateur pour correction

    Jérôme.

    • [^] # Re: Le "fautif" est MySQL et pas PHP

      Posté par  . Évalué à 1 (+0/-0).

      Merci. A tous en fait.
      Je vais effectivement mettre un contrôle au niveau du formulaire et modifier quelques paramètres de la BDD, mais je vais laisser le mode strict.
      Symfony aurait effectivement été mieux : si j'ai bien compris déjà l'utilisation de Doctrine permet de faire des choses bien plus rigoureuses et secure… mais sur ce vieux projet qui a été développé sans rien, il faudrait tout ré-écrire avec Symfony !

      • [^] # Re: Le "fautif" est MySQL et pas PHP

        Posté par  (site Web personnel) . Évalué à 2 (+1/-0).

        Pas la peine d'aller jusque là !

        Symfony peut s'utilise soit en framework complet, soit en utilisant uniquement certains de ces composants.

        Par exemple pour le composant Validator : https://symfony.com/doc/current/components/validator.html#usage

        Par exemple :

        Tu utilises composer pour installer les composants nécessaires :

        composer require symfony/validator

        Puis tu peux y accéder au-dit composant

        <?php
        
        require 'vendor/autoload.php';
        
        use Symfony\Component\Validator\Constraints as Assert; 
        use Symfony\Component\Validator\Validation;
        
        $validator = Validation::createValidator();
        
        $violations = $validator->validate('jerome-example.com', [
            new Assert\Email,
            new Assert\NotBlank(),
        ]);
        
        if (0 !== count($violations)) { 
            foreach ($violations as $violation) {
                echo $violation->getMessage(). PHP_EOL;
            }
        }

        Si tu exécutes ce bout de code tu auras doit au message d'erreur suivant : "This value is not a valid email address."

        Je t'invite à lire la documentation

        Jérôme

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.