Problème de transcodage UTF-8 (caractère 195)

probleme de transcodage utf-8 caractere 195Problématique

Je suis amené à récupérer des données sur un de mes sites (codé en UTF-8) et à les basculer dans un autre après quelques traitements.

J’ai donc programmé un bout de code en PHP qui fonctionne sur mon serveur local, paramétrer également en UTF-8 et à mettre à jour par programme les tables WordPress de mon nouveau site par l’instruction mysqli_query.

Or que constaté-je de mes yeux horrifiés ? Que tous les caractères accentués et autres « ç » qui font le charme de notre belle langue apparaissent sous la forme que vous avez déjà tous observés (faites donc une recherche un peu poussée sur Amazon et vous verrez) : les fameux é et autres è … Inesthétiques au possible, illisibles et qui font franchement aussi négligé qu’une tâche de ketchup sur un plastron de smoking, tel que j’en porte tous les soirs pour le dîner depuis que j’ai vu et revu Downton Abbey.

J’essaie tous les utf8_encode, utf8_decode, iconv de PHP : rien n’y fait. Essayez de forcer le codage en UTF-8 d’un texte déjà en UTF-8, c’est spectaculaire !

Après une longue errance dans les forums, je constate que ce problème est très répandu et que ceux qui prétendent qu’il est facile à résoudre n’ont pas dû programmer depuis la chute de Bismarck.

Il faut admettre que dans la situation où je m’étais mis, je passais par un nombre de couches qui avaient toutes les raisons de ne pas tomber d’accord.

Solution

Le consensus ayant ses limites, j’ai donc décidé de passer un peu en force et de rappeler à tout ce petit monde (PHP, mySQL, WordPress) qui était le patron. Et pour ça, il existe une excellente instruction à passer à mySQL juste après la connexion (ou dans la chaîne de connexion). C’est (roulements de tambour …) :

SET NAMES UTF8

Et tout rentre dans l’ordre, je peux écrire « éçà€ » et j’obtiendrai bien « éçà€ ».

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

MySQL. Attention au CONCAT avec argument NULL !

Problématique

Un grand classique mais c’est toujours là-dessus qu’on se plante … Vous voulez dans un champ concaténer, admettons, titre, prénom et nom. Mais comme tout le monde n’est pas docteur, le champ « docteur » est nullable et vous ne vous êtes pas privés.

Vous faites un gros update genre :

UPDATE matable SET nomcomplet=CONCAT (titre, prenom, nom)

et, amère surprise, vous obtenez des champs « nomcomplet » vides.

Le pire est lorsque, comme dans le cas de votre serviteur, vous avez négligemment laissé des champs « titre » à NULL et d’autres blancs (= »)

Solution

Alors on se le tient pour dit, et quelqu’un aurait pu me le rappeler, j’avais oublié, que :

Si un des arguments du CONCAT est NULL, CONCAT renvoie NULL

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

POUR EN SAVOIR PLUS : les derniers livres parus sur MySQL sont sur

DerniersParus.com » MySQL

MySQL. Récupérer rapidement une sauvegarde

Problématique

Vous utilisez phpMyAdmin, vous venez de supprimer un champ malencontreusement et avez perdu des informations précieuses. C’est arrivé aux meilleurs d’entre nous.

Si vous n’avez pas fait de sauvegarde, je ne peux rien pour vous sauf vous dire que vous ne faites effectivement pas partie des meilleurs.

Sinon c’est tout simple.

Solution

Attention la solution que je vous propose ne fonctionne que pour les tables au format MyISAM. Elle fonctionne peut-être pour les autres mais je ne les utilise pas donc je ne vous promets rien. Mais au niveau de désespoir où vous en êtes, essayez d’adapter ma solution.

Sachant que pour la table matable, il y a trois fichiers : matable.frm, matable.MYD, matable MYI

  1. renommez vos mauvais fichiers
  2. copiez les bons à partir de votre sauvegarde
  3. vous me direz que vous savez ça depuis MSDOS 1.25 (on ne rit pas, ça a existé et j’ai débuté là-dessus). Certes, certes. Mais la valeur ajoutée de mon post est ici : n’oubliez pas de redémarrer Apache et mySQL parce que phpMyAdmin conserve en mémoire la structure précédente et ne comprend pas , sinon, vos nouveau fichiers

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

POUR EN SAVOIR PLUS : les derniers livres parus sur MySQL sont sur

DerniersParus.com » MySQL

MySQL. BULK UPDATE (aka grosse mise à jour)

Problématique

Vous voulez mettre tous les champs d’une table à jour à partir d’une autre table.

Vous pouvez par exemple vouloir mettre à jour une table distante à partir d’une table locale.

Vous pouvez, comme je le faisais quand j’étais petit, le faire par programme et mettre à jour ligne à ligne. Le programme n’est pas long à faire mais l’exécution …

Solution

Le mieux est de mettre les données dans une table temporaire qu’on appellera source.

La méthode généralement utilisée (parce que c’est la bonne) est la suivante :

CREATE TABLE IF NOT EXISTS source (
champ1 int(11) NOT NULL,
champ2 int(11) DEFAULT NULL,
champ3 int(11) DEFAULT NULL
)
les types de champ ne sont qu’un exemple

de la charger ensuite par un

INSERT INTO source (champ1, champ2, champ3) FROM SELECT ( …)

et d’exporter ensuite la table. Mais jusque là vous saviez tout ça.

Comment faire le BULK UPDATE ? En posant source le nom de la table … source et dest le nom de la table … dest (vous aviez deviné ?) qui sera alimentée. La commande est la suivante.

UPDATE dest  INNER JOIN source

ON dest.IDdest=source.IDsource

SET dest.champdest1=source.source1, …,  dest.champdestn=source.champsourcen

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

POUR EN SAVOIR PLUS : les derniers livres parus sur MySQL sont sur

DerniersParus.com » MySQL

MySQL. Pister les requêtes lentes

Problématique

Il faut toujours suivre la performance des requêtes d’une base de données. Au début, elle est toute petite et mignonne avec ses 250 entrées et toute requête même la plus lamentable a de bonnes performances. Mais, ouille, six mois après, on est passé à 2500000 entrées et là ça ne va plus du tout. J’exagère ? A peine.

Rien de tel que de mettre en place une surveillance en indiquant à MySQL de vous montrer les requêtes trop lentes par rapport à un seuil que vous pouvez fixer librement.

Solution

Nous avons vu dans les deux posts précédents comment trouver la valeur d’une variable globale et comment la modifier. Croyez-vous que c’était comme ça, pour rire, gratuitement ? Que nenni ! Avec un sens de la pédagogie qui, je le vois bien, vous laisse pantois, les bras ballants, il s’agissait de vous amener doucement à cette petite merveille.

Quatre variables globales sont concernées :

  • slow_query_log : positionné à ON, les requêtes longues sont enregistrées, à OFF elles ne le sont pas. Pour mettre à ON, on modifiera la valeur à 1. Et pour la mettre à OFF on fera comment ? Interro écrite demain matin.
  • slow_query_log_file : fichier de log, sa valeur par défaut est sous Ubuntu /var/run/mysqld/mysqld-slow.log
  • long_query_time : seuil en millisecondes au-delà duquel, vous considérez qu’une requête est trop longue. Sa valeur par défaut est de 10 ms. Je suggère 5 ms si vous voulez faire un examen approfondi quitte à remonter ce plafond ultérieurement
  • min_examined_row_limit : le nombre minimum de lignes que cette requête doit avoir examinées. Par exemple, si vous remontez d’un bloc un million de lignes (ça vous regarde …), il ne faut pas s’attendre à un temps de 0.1 ms. Vous avez déjà optimisé ce type de requête (la meilleure optimisation étant de les éviter), vous ne voulez plus les logger, vous pouvez donc mettre la valeur de cette variable à 500000.

Le plus couramment, on fera le changement suivant

mysql>SET GLOBAL slow_query_log=1;

mysql>SET GLOBAL long_query_time=10;

Et maintenant comment lirons-nous le résultat ? Sous le shell Ubuntu (ou autre), il suffira de taper la commande :

mysqldumpslow -verbose /var/run/mysqld/mysqld-slow.log (si vous n’avez pas changé le nom du fichier de log par défaut)

Ensuite, il n’y a plus qu’à optimiser si nécessaire

ET LE TOUR EST  JOUÉ !ALORS ON DIT MERCI QUI ?

Et pour une formation plus approfondie, une page sur les derniers livres parus sur MySQL sur DerniersParus.com

MySQL. Modifier la valeur d’une variable globale

Problématique

Vous voulez modifier la valeur d’une variable globale. Comment faire ?

Solution

Très simple quand on sait. Dans l’administration de mysql, vous tapez après le prompt mysql>

SET GLOBAL la_variable_a_changer=sa_valeur;

attention, si la variable est locale et que vous oubliez le GLOBAL, MySQL vous préviendra

mais si vous oubliez le « ; » en fin de ligne, vous risquez d’attendre et donc de vous inquiéter en vous demandant ce qui se passe, et donc de faire de l’acidité, et donc d’attraper un ulcère à l’estomac.

Un exemple dans le prochain post

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

Et pour une formation plus approfondie, une page sur les derniers livres parus sur MySQL sur DerniersParus.com

MySQL. Afficher les variables globales et leur valeur

Problématique

Vous voulez optimiser vos requêtes MySQL. Pas le choix, c’est obligatoire. Ou modifier le cache des requêtes. Souvent utile. Il faut pour cela modifier ce que MySQL appelle les variables globales.

Première question question : comment trouver leur valeur ?

Solution 1

Dans phpMyAdmin, vous cliquez en haut sur la racine « localhost » et puis sur « Variables » et la liste complète s’affiche.

phpAdminVariables

L’exemple ne vous affiche que les 4 premières variables mais il y en a beaucoup plus. Et comme vous le remarquez, dans la colonne « Documentation », un « ? » vous envoie sur la documentation en ligne de la variable en question.

Donc vous savez comment trouver la valeur d’une variable globale et, ce qui n’est pas négligeable, comment trouver ce qu’elle fait.

Solution 2

Vous allez directement dans l’administration de mysql et après le prompt mysql>  vous tapez :

mysql>SHOW VARIABLES

mais dans ce cas vous n’aurez pas l’explication de la fonction de la variable. Peut-être la connaissez-vous déjà.

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

Et pour une formation plus approfondie, une page sur les derniers livres parus sur MySQL sur DerniersParus.com

MySQL. Vérifier une requête

MySQLProblématique

Pour bien comprendre la problématique, il fallait lire l’article précédent (SEO. PageSpeed et PHP). Mais on va supposer que vous ayez un GROS doute sur la performance d’une requête. Je ne dis pas qu’elle renvoie des choses que vous n’attendiez pas (ou qu’elle ne renvoie pas ce que vous attendiez). Je parle du cas où le résultat est correct. Mais très lent.

Solution

Tout simple. Vous allez dans phpMyAdmin et vous lancez à la main la requête suspecte. MySQL vous indique le temps d’exécution :

  • supérieur à 0.01 s, c’est suspect
  • supérieur à 0.1s, c’est mauvais, il faut faire quelque chose
  • supérieur à 1s, c’est catastrophique, voir plus haut

Il se peut aussi que la requête soit correcte mais qu’elle vous renvoie 324 256 entrées. C’est long à ramener et c’est logique. Mais ce sera encore plus long à afficher et il s’agit là d’un problème de design et de conception et non de requête.

Bref !

Cliquez maintenant sur le choix [Expliquer SQL]. Vous verrez qu’il répète votre requête mais précédée cette fois du mot-clef EXPLAIN. Il vous renverra en particulier les index possibles et le nombre de rows renvoyés.

Une première indication :

  • s’il ne renvoie pas de nom d’index
  • et/ou si il vous renvoie un nombre étonnamment grand de lignes

ça signifie probablement qu’il vous manque une clef d’index et que votre requête balaie donc séquentiellement toute la table.

C’est une erreur de débutant. Tellement de débutant qu’on n’y pense même pas. Et pourtant, elle vient de m’arriver. ON NE RIGOLE PAS.

Pour plus d’informations sur la clause SQL EXPLAIN, je vous renvoie au chapitre de la doc MySQL Syntaxe de EXPLAIN. C’est la base de la fonctionnalité de phpMyAdmin. Celle-ci suffit largement à mon avis.

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

SEO. PageSpeed et PHP

Problématique

Votre site est beau mais beau ! Et par un acquis de conscience qui vous honore, vous vous dites que « beau » c’est une bonne chose pour les utilisateurs mais que Google est assez peu sensible à l’esthétique : il faut aussi que le chargement des pages soit rapide.

On ne répétera jamais assez à quel point Google est sensible au temps de chargement des pages.

Vous utilisez donc PageSpeed, excellent outil que vous propose Google.

Et après quelques ajustements, vous arrivez à un score de 97% pratiquement parfait.

Et pourtant, quelques temps après vous vous apercevez que les temps d’accès sont mauvais. Mais mauvais !

Solution

Ou du moins début de solution. N’oubliez pas que PageSpeed analyse la page html qui résulte de tous vos traitements. Donc si vous avez une requête catastrophiquement lente dans votre page PHP, PageSpeed n’y verra que du feu et ne vous avertira donc pas !

Vérifiez donc vos requêtes PHP/MySQL et pour ce faire, lisez le post suivant.

ET LE TOUR EST JOUÉ ! ALORS ON DIT MERCI QUI ?

Et pour une formation plus approfondie, une page sur les derniers livres parus sur MySQL sur DerniersParus.com

Pourquoi ce « blog-note » informatique ?

Vous trouvez facilement dans les docs en ligne ou sur Google vous ? Moi pas ?

Comme tous ceux qui programment, j’ai parfois des difficultés.

Alors je cherche dans les manuels online.

  • PHP ? Splendide : on cherche, on trouve et ça marche
  • MySQL ? Pas mal : on cherche, on trouve et ça marche si on comprend ce qu’ils racontent
  • MSDN ? Dur : on cherche, on ne trouve pas toujours et quand on trouve, rien ne dit que ça marche.
  • Les forums ? Quand on a passé la couche des fautes d’orthographes, on trouve des réponses manifestement pas essayées que le geek moyen a entendu après sa 5e bière voire son 3e pétard donc auxquelles il a pas pigé un broc. Enervant.

Alors voilà pourquoi ce « blog-note » informatique

Donc ce blog, un forum de plus ?

Non, ce que j’ai essayé ça marche … Ou alors j’aurais mal expliqué et dans ce cas prévenez-moi.

Alors comme je suis d’un naturel jovial et généreux, je vous fais partager mes solutions. A charge de revanche … Et puis comme je suis prudent, c’est un moyen de ne pas oublier 6 mois après comment j’avais réussi à me dépanner.

Petit détail, je programme en VB.NET (même si je connais le C, ce roi des langages, mais VB.NET a une meilleure interopérabilité avec Microsoft Office), en PHP, je me mets à Java (donc n’attendez pas trop de tuyaux là-dessus pour le moment). Je fais du HTML et du WordPress pour mes sites. Et à une époque d’égarement, j’ai utilisé SQL Server en local mais j’ai cru que mon PC était retourné dans les années 80. Et je suis passé à MySQL (en attendant PostgreSQL dont un ami me vante les charmes torrides à chaque rencontre).

En outre, j’ai une assez longue expérience. J’ai connu MSDOS 1.25 les p’tits gars ! Il n’y avait pas de répertoires, juste 16 disques virtuels de A à P, ce qui ne nous rajeunit pas.

Enfin malgré les apparences, je n’ai jamais été salarié comme informaticien mais je me suis toujours fabriqué des outils informatiques pour mon utilisation personnelle ou professionnelle. Donc, attendez-vous à du pratico-pratique.