OVH Community, votre nouvel espace communautaire.

MySQL longtext texte tronqué à ~75k de caractères


tristanIT
26/08/2016, 09h34
Je développe en local avec Atom.
Toutes mes pages sont en UTF-8.

Le problème vient du texte (le texte que je réutilisais pour générer ma newsletter) qui lui n'était pas inséré en BDD en UTF-8, mais du coup j'ai corrigé ceci, c'est beaucoup plus propre que d'utiliser des utf8_decode

Merci pour ton aide.
A+

romainovh
26/08/2016, 08h27
Il s'agissait donc bien d'un caractère qui pose problème :-)

J'imagine que pour créer ton html, tu utilises une page page avec un éditeur de texte comme ckeditor ?
Si c'est le cas, es-tu sûr que cette page est bien encodée en UTF-8 ?
Tu peux aussi vérifier avec les dev Tools de Chrome ou Firebug l'encodage de tes données au moment de l'envoi au serveur.

Vérifie aussi si ton caractère "carré" est bien en UTF8, et pas UTF16 ou UTF32.

a+

tristanIT
25/08/2016, 16h32
Cette fonction fait parti d'un module que j'ai créé, elle ne fait pas partie d'AcyMailing, mais je me calque sur ce module pour créer ma newsletter.

J'ai résolu mon problème qui est pour le moins étrange.
Il s'agissait d'un problème d'encodage de certains caractères.

Effectivement lorsque je faisais un echo de ma variable $body, les 100k s'affichait correctement, mais MySQLi, PDO ou MySQL ne devait pas apprécier ce caractère (le signe carré) et tronquait la chaîne à l'insertion.

J'ai appliqué un utf8_decode sur toute la chaîne en attendant, et ça fonctionne.
Maintenant il va surtout falloir que je me mette en quête de la source du problème car ce n'est jamais bon d'utiliser ces fonctions

romainovh
25/08/2016, 13h24
Bonjour,

Apparemment il ne s'agit pas d'un problème Joomla qui ne gère pas de newsletter, mais peut-être de l'extension AcyMailing, non ?

Dans ton html qui est tronqué, as-tu repéré si l'insertion est coupée à un caractère spécifique, juste avant ou juste après la coupure ?
-> par exemple, essaie de couper en 2 ton html et d'insérer "partie 1 + partie 1 encore", et voir ce qui est inséré.

Bon courage et tiens nous au courant de tes avancées ;-)

tristanIT
25/08/2016, 12h18
Bonjour et merci pour votre aide.

J'ai essayé beaucoup de chose : une chose est sûr c'est un problème bien vicelard (je souris mais en réalité j'en pleure... )
Première chose (qui de toute façon ne pouvait pas faire de mal) j'ai migré la BDD d'une "perso" à une "pro" chez OVH.

Mon site est un site Joomla (3.6),
Avant ce problème mon site utilisait l'extension MySQLi puis j'ai essayé PDO, le soucis n'a pas évolué.

J'ai tenté une insertion de données via un script PHP tout simple avec ton exemple puis dans ma table de newsletter avec les 100k de données : tout est fonctionnel, rien n'est tronqué.

Tout m'indique que le problème serait finalement applicatif (contrairement à ce que je croyais) ; ce que j'ai dû mal à comprendre au vu de la petitesse / simplicité de mon code, lu et relu à chaud et à froid.
D'autant qu'il est fonctionnel en local, la version de PHP est la même, seule la version de MySQL diffère (OVH : 5.5 ; local : 5.7).

Je n'ai rien trouvé sur internet qui concerne ce bug sur Joomla. J'ai commencé à fouillé dans le code source du constructeur de requête fourni par Joomla mais je vais également essayer de me rapprocher de la communauté.

Code:
  public static function addAcymailingMail($body) {
    $db    = JFactory::getDbo();
    $query = $db->getQuery(true);

    $user = JFactory::getUser();
    setlocale(LC_TIME, 'fr_FR.utf8','fra'); 
    $date = strftime("%B %Y"); 

    $subject    = $db->quote("Mon super titre... ($date)");
    $body       = $db->quote($body);
    $altbody    = $db->quote('');
    $published  = 0;
    $created    = time();
    $userid     = $user->id;
    $tempid     = 0;
    $key        = $db->quote(self::acymailing_generateKey(8));
    $sentby     = $user->id;

    $columns = array('subject', 'body', 'altbody', 'published', 'created', 'userid', 'tempid', 'key', 'sentby');
    $values  = array($subject, $body, $altbody, $published, $created, $userid, $tempid, $key, $sentby);

    $query->insert($db->quoteName('#__acymailing_mail'))
          ->columns($db->quoteName($columns))
          ->values(implode(',', $values));

    $db->setQuery($query);
    $db->execute();
    
    return $db->insertid();
  }

romainovh
23/08/2016, 22h56
Salut,

Ta question est intéressante, j'aimerais bien savoir quel est le problème.
En attendant d'autres réponses, tu peux faire quelques tests, directement sur phpmyadmin par exemple :

Insérer uniquement des caractères "simples", comme des A. J'ai fait ce test sur une base mutu :

Code:
create table tttt (colonne longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci);
insert into tttt values (REPEAT('A', 10000000));
SELECT char_length(colonne) nb_chars,length(colonne) nb_octets FROM tttt;
Les 10Mo ont été insérés. C'est bien la taille de ma table. Le select donne 10000000 caractères et 10000000 octets.
Avec des 'é', ça ne m'insère rien pour 10 millions de caractères (NULL), mais 200 000 passent (et le select donne 200000 caractères et 400000 octets).

Tu peux aussi tester cette dernière requête avec tes données tronquées, voir ce que ça donne ?
Tu utilises quelle extension (PDO, mysqli,...) pour exécuter tes requêtes ?

tristanIT
23/08/2016, 11h16
Bonjour,

Depuis l'administration de mon site, j'ai créé un formulaire avec uniquement 1 bouton : celui-ci me permet de générer automatiquement le code HTML de ma newsletter.

En local, l'enregistrement se fait correctement, ça me donne 100k de caractères.
En prod, l'enregistrement est tronqué à 75k.

Mon texte est en UTF-8.
J'ai un champ "body" de type longtext, encodage utf8_general_ci.

J'ai écarté deux hypothèses :
- le taille disponible pour un champ de type longtext qui offre ~4 milliards d'octets (divisé par 4 pour des caractères UTF-8, il reste quand même 1 milliards de caractères dispos)
- la taille max du post, vu que mon code HTML est entièrement généré depuis le code.

En re-vérifiant mon code je ne vois pas ce qui pourrait poser soucis à ce niveau là, je penche plutôt pour un problème côté serveur ou un limitation de MySQL ou de mon offre ? (OVH Pro)

Merci

EDIT : ma base de données est une OVH Perso 400Mo ; peut-être avez-vous un "système de buffer" qui limite à 75k sur ce type de BDD ? faut-il envisager de migrer sur BDD OVH Pro ?

EDIT 2 : lorsque je fais un echo de ma variable avant insertion en BDD, tout ce qui devrait être enregistrer s'affiche bien, c'est uniquement à l'insertion que le texte est tronqué.