614 shaares
8 results
tagged
utf-8
Lien précédent : http://www.olissea.com/mb/links/1/?ibR8_g
EDIT: J'ai trouvé ce problème ceci dit: https://bugs.php.net/bug.php?id=65045
Mais j'ignore si je suis vraiment concerné : ça dépend en effet si mon script capture ces séquences à problèmes mais il me semble qu'il ne capture que les séquences valides de 4 bytes, donc pas de problème normalement.
Également, j'ai pas trop compris comment ça se fait, mais lorsque j'applique htmlspecialchars sur les séquences données sur la page, l'output n'est pas vide. Ne devrait-il pas l'être (vu que htmlspecialchars renvoie stupidement une chaîne vide lorsqu'il reçoit de l'UTF-8 invalide normalement ?).
Mmmmmh.
</EDIT>
"Plop.
Après mainte péripéties et échecs, je pense avoir trouver quelque chose de "potable".
Voir le code avec coloration syntaxique (un peu différent, manque une source) : http://sebsauvage.net/paste/?e249576d75ee9946#jBpv2UCufTQ4UC2WnTtM11gfolfGkQi61brf11pFORU=
<?php
# "😒" est codé sur 4 bytes
$body = 'lol😒a☺';
echo 'before: ',$body,'<br />'; # Output: lol😒a☺
echo 'length: ',strlen($body),'<br />'; # Output: 11 (😒 = 4, ☺ = 3)
# Le but est de remplacer uniquement les caractères de plus de 3 bytes par leur entité HTML.
# Afin d'obtenir ce code dans le cas de notre exemple
echo '😒','<br />'; # Fourni par https://duckduckgo.com/?q=html+%F0%9F%98%92
# Récupération des caractères de plus de 3 bytes uniquement
# Source: http://stackoverflow.com/a/1401716/1524913
# $body = preg_replace('/[\xF0-\xF7][\x80-\xBF]{3}/', '�', $body); # Yeah! It works!
# Ne fonctionne pas. htmlentities ne connaît pas tous les caractères unicode ( http://stackoverflow.com/a/13942507/1524913 )
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return htmlentities($m[0], ENT_COMPAT, 'UTF-8');}, $body); # Ignore complètement 😒
# La solution proposée au lien précédemment cité : Ne fonctionne pas non plus
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return str_replace('\\u','&#x',trim(json_encode($m[0]),'"')).';';}, $body);
# Output: lol��a☺ car json_encode considère ça comme deux caractères de deux bytes et renvoie "\ud83d\ude12"
# Ne fonctionne pas ( http://php.net/manual/en/function.htmlentities.php#107985 )
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return mb_encode_numericentity($m[0], array(0x0, 0xffff, 0, 0xffff), 'UTF-8');}, $body); # Ignore complètement 😒
# Fonctionne !!! Mais renvoie 😒 au lieu de 😒 (Pas vraiment un problème en soit)
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return mb_convert_encoding($m[0], 'HTML-ENTITIES', 'UTF-8');}, $body);
# Si on veut vraiment la version hexadécimal
$body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return '&#x'.dechex(substr(mb_convert_encoding($m[0], 'HTML-ENTITIES', 'UTF-8'), 2)).';';}, $body);
echo 'after: ',$body,'<br />'; # Output: lol😒a☺
?> "
EDIT: J'ai trouvé ce problème ceci dit: https://bugs.php.net/bug.php?id=65045
Mais j'ignore si je suis vraiment concerné : ça dépend en effet si mon script capture ces séquences à problèmes mais il me semble qu'il ne capture que les séquences valides de 4 bytes, donc pas de problème normalement.
Également, j'ai pas trop compris comment ça se fait, mais lorsque j'applique htmlspecialchars sur les séquences données sur la page, l'output n'est pas vide. Ne devrait-il pas l'être (vu que htmlspecialchars renvoie stupidement une chaîne vide lorsqu'il reçoit de l'UTF-8 invalide normalement ?).
Mmmmmh.
</EDIT>
"Plop.
Après mainte péripéties et échecs, je pense avoir trouver quelque chose de "potable".
Voir le code avec coloration syntaxique (un peu différent, manque une source) : http://sebsauvage.net/paste/?e249576d75ee9946#jBpv2UCufTQ4UC2WnTtM11gfolfGkQi61brf11pFORU=
<?php
# "😒" est codé sur 4 bytes
$body = 'lol😒a☺';
echo 'before: ',$body,'<br />'; # Output: lol😒a☺
echo 'length: ',strlen($body),'<br />'; # Output: 11 (😒 = 4, ☺ = 3)
# Le but est de remplacer uniquement les caractères de plus de 3 bytes par leur entité HTML.
# Afin d'obtenir ce code dans le cas de notre exemple
echo '😒','<br />'; # Fourni par https://duckduckgo.com/?q=html+%F0%9F%98%92
# Récupération des caractères de plus de 3 bytes uniquement
# Source: http://stackoverflow.com/a/1401716/1524913
# $body = preg_replace('/[\xF0-\xF7][\x80-\xBF]{3}/', '�', $body); # Yeah! It works!
# Ne fonctionne pas. htmlentities ne connaît pas tous les caractères unicode ( http://stackoverflow.com/a/13942507/1524913 )
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return htmlentities($m[0], ENT_COMPAT, 'UTF-8');}, $body); # Ignore complètement 😒
# La solution proposée au lien précédemment cité : Ne fonctionne pas non plus
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return str_replace('\\u','&#x',trim(json_encode($m[0]),'"')).';';}, $body);
# Output: lol��a☺ car json_encode considère ça comme deux caractères de deux bytes et renvoie "\ud83d\ude12"
# Ne fonctionne pas ( http://php.net/manual/en/function.htmlentities.php#107985 )
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return mb_encode_numericentity($m[0], array(0x0, 0xffff, 0, 0xffff), 'UTF-8');}, $body); # Ignore complètement 😒
# Fonctionne !!! Mais renvoie 😒 au lieu de 😒 (Pas vraiment un problème en soit)
# $body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return mb_convert_encoding($m[0], 'HTML-ENTITIES', 'UTF-8');}, $body);
# Si on veut vraiment la version hexadécimal
$body = preg_replace_callback('/[\xF0-\xF7][\x80-\xBF]{3}/', function($m){return '&#x'.dechex(substr(mb_convert_encoding($m[0], 'HTML-ENTITIES', 'UTF-8'), 2)).';';}, $body);
echo 'after: ',$body,'<br />'; # Output: lol😒a☺
?> "
Any idea anyone? (Thanks in advance :))
EDIT: Solution: http://www.olissea.com/mb/links/1/?_F3x0g
EDIT: J'ai trouvé ça mais ça ne fonctionne pas chez moi malheureusement . :( J'ignore pourquoi. http://webcollab.sourceforge.net/unicode.html ( Character Validation )
"Helloooo
Quelqu'un aurait-il une idée afin de stocker de l'UTF-8 façon correcte avec MySQL d'une version antérieur à MySQL 5.5 ?
Background: Avant MySQL5.5, il n'y a que l'option utf8 et non l'option utf8mb4 permettant (enfin!) de stocker des caractères codés sur 4 bytes ("I wish I was kidding" - Source ).
What I've tried so far / Ce que j'ai déjà essayé :
J'avais pensé à peut-être utilisé un champ de type BINARY (ou BLOB), ce qui me permettrait d'y stocker ce que j'y veux (le problème serait donc résolu) mais cela apporte aussi son lot d'inconvénients…
- Memory overhead pour accéder à des champs de type TEXT ou BLOB. (Boarf, pas très grave, j'utilise déjà un champ TEXT)
- Impossibilité d'utiliser ses champs dans une clause WHERE et donc, je suppose, également dans un LIKE afin de faire une recherche dans la base de données. Right?
(J'aurais du garder les sources parlant de ces dits inconvénients… sorry)
Côté PHP je pourrais essayer de détecter les caractères sur 4 bytes (ça serait lourd par contre) mais j'ignore même ce que j'en ferais… Les convertir en entité HTML ?
Je refuse de me mettre à utiliser htmlentities au lieu d'htmlspecialchars :( (fin, ça serait trop triste quoi)"
EDIT: Solution: http://www.olissea.com/mb/links/1/?_F3x0g
EDIT: J'ai trouvé ça mais ça ne fonctionne pas chez moi malheureusement . :( J'ignore pourquoi. http://webcollab.sourceforge.net/unicode.html ( Character Validation )
"Helloooo
Quelqu'un aurait-il une idée afin de stocker de l'UTF-8 façon correcte avec MySQL d'une version antérieur à MySQL 5.5 ?
Background: Avant MySQL5.5, il n'y a que l'option utf8 et non l'option utf8mb4 permettant (enfin!) de stocker des caractères codés sur 4 bytes ("I wish I was kidding" - Source ).
What I've tried so far / Ce que j'ai déjà essayé :
J'avais pensé à peut-être utilisé un champ de type BINARY (ou BLOB), ce qui me permettrait d'y stocker ce que j'y veux (le problème serait donc résolu) mais cela apporte aussi son lot d'inconvénients…
- Memory overhead pour accéder à des champs de type TEXT ou BLOB. (Boarf, pas très grave, j'utilise déjà un champ TEXT)
- Impossibilité d'utiliser ses champs dans une clause WHERE et donc, je suppose, également dans un LIKE afin de faire une recherche dans la base de données. Right?
(J'aurais du garder les sources parlant de ces dits inconvénients… sorry)
Côté PHP je pourrais essayer de détecter les caractères sur 4 bytes (ça serait lourd par contre) mais j'ignore même ce que j'en ferais… Les convertir en entité HTML ?
Je refuse de me mettre à utiliser htmlentities au lieu d'htmlspecialchars :( (fin, ça serait trop triste quoi)"
Juste avoir une fonction correcte, facile à utiliser, qui ne me renvoie pas une chaîne de caractère vide si l'input contient de l'utf-8 invalide.
Et, dût ma contrainte technique, la seule alternative que j'ai (ENT_IGNORE) est déconseillée … Doh.
( EDIT: [Je raconte ma vie]
Pis PHP ne cesse de m'épater dans le mauvais sens et plus j'investigue plus j'suis aberré.
M'enfin … ça n'a pas que du mauvais, ça m'aide à me forcer à faire plus de Python et moins de PHP.
Pour ceux qui continuent à me demander pourquoi je fais encore du PHP je répondrais que les vieilles habitudes ont la vie dure, qu'il faudrait que je transcrive tout mes scripts PHP vers Python, c'est beaucoup de boulot … tellement qu'on préfère souvent la simplicité de continuer les vieilles habitudes et/ou quand on a pas le choix / temps et qu'on a besoin que qu'une appli ou autre soit fonctionnelle dans les temps. Et malheureusement, j'ai encore trop de setup à faire pour que je puisse le faire via Python, mais ça vient ptit à ptit. ☺
)
EDIT 2:
Je pense que le plus simple/efficace serait, comme je l'avais fait une fois sans vraiment avoir étudier la question en profondeur, serait de juste réimplémenter la fonction via str_replace qui lui est apparemment 100% utf-8 safe.
À vérifier.
Et, dût ma contrainte technique, la seule alternative que j'ai (ENT_IGNORE) est déconseillée … Doh.
( EDIT: [Je raconte ma vie]
Pis PHP ne cesse de m'épater dans le mauvais sens et plus j'investigue plus j'suis aberré.
M'enfin … ça n'a pas que du mauvais, ça m'aide à me forcer à faire plus de Python et moins de PHP.
Pour ceux qui continuent à me demander pourquoi je fais encore du PHP je répondrais que les vieilles habitudes ont la vie dure, qu'il faudrait que je transcrive tout mes scripts PHP vers Python, c'est beaucoup de boulot … tellement qu'on préfère souvent la simplicité de continuer les vieilles habitudes et/ou quand on a pas le choix / temps et qu'on a besoin que qu'une appli ou autre soit fonctionnelle dans les temps. Et malheureusement, j'ai encore trop de setup à faire pour que je puisse le faire via Python, mais ça vient ptit à ptit. ☺
)
EDIT 2:
Je pense que le plus simple/efficace serait, comme je l'avais fait une fois sans vraiment avoir étudier la question en profondeur, serait de juste réimplémenter la fonction via str_replace qui lui est apparemment 100% utf-8 safe.
À vérifier.
J'essaie de trouver quelle serait la meilleure utilisation de htmlspecialchars si on ne possède pas encore PHP 5.4 (contraintes techniques).
D'une part, par défaut, si vous passez une chaîne contenant de l'UTF-8 invalide, htmlspecialchars vous retournera une chaîne complètement vide. ("Pratique")
Pour remédier à ça, il vous faut utiliser ENT_IGNORE ou ENT_SUBSTITUTE. ........ MAIS la doc déconseille l'utilisation de ENT_IGNORE pour des raisons de sécurité. ( http://unicode.org/reports/tr36/#Deletion_of_Noncharacters )
(Source: http://stackoverflow.com/q/11088953/1524913 )
Seulement voilà, ENT_SUBSTITUE est uniquement disponible à partir de PHP 5.4.0. (Donc je fais quoi… ?)
Notez égaaaaaaalement qu'il est impossible de spécifier les paramètres par défaut de htmlspecialchars et qu'il vaudrait mieux donc que vous créez votre propre wrapper.
Puis j'ai également trouvé cette perle … jugez par vous-même. ._."
"Error handling in htmlspecialchars before PHP 5.4 was … uhm, let’s call it “unintuitive”:
If you passed a string containing an “invalid code unit sequence” (which is Unicode slang for “not encoded correctly”) htmlspecialchars would return an empty string. Well, okay, so far so good. The funny thing was that it additionally would throw an error, but only if error display was disabled. So it would only error if errors are hidden. Nice, innit?"
(Source: http://nikic.github.io/2012/01/28/htmlspecialchars-improvements-in-PHP-5-4.html)
Cette page-ci n'est pas mal non plus: http://stackoverflow.com/q/13745353/1524913
D'une part, par défaut, si vous passez une chaîne contenant de l'UTF-8 invalide, htmlspecialchars vous retournera une chaîne complètement vide. ("Pratique")
Pour remédier à ça, il vous faut utiliser ENT_IGNORE ou ENT_SUBSTITUTE. ........ MAIS la doc déconseille l'utilisation de ENT_IGNORE pour des raisons de sécurité. ( http://unicode.org/reports/tr36/#Deletion_of_Noncharacters )
(Source: http://stackoverflow.com/q/11088953/1524913 )
Seulement voilà, ENT_SUBSTITUE est uniquement disponible à partir de PHP 5.4.0. (Donc je fais quoi… ?)
Notez égaaaaaaalement qu'il est impossible de spécifier les paramètres par défaut de htmlspecialchars et qu'il vaudrait mieux donc que vous créez votre propre wrapper.
Puis j'ai également trouvé cette perle … jugez par vous-même. ._."
"Error handling in htmlspecialchars before PHP 5.4 was … uhm, let’s call it “unintuitive”:
If you passed a string containing an “invalid code unit sequence” (which is Unicode slang for “not encoded correctly”) htmlspecialchars would return an empty string. Well, okay, so far so good. The funny thing was that it additionally would throw an error, but only if error display was disabled. So it would only error if errors are hidden. Nice, innit?"
(Source: http://nikic.github.io/2012/01/28/htmlspecialchars-improvements-in-PHP-5-4.html)
Cette page-ci n'est pas mal non plus: http://stackoverflow.com/q/13745353/1524913
Je sais que shaarli n'a pas de problème pour le stocker car il stocke tout dans des fichiers il me semble.
Par contre, si mysql est mal configuré (trop souvent le cas), le message se voit tronqué :p
On va donc tester vos agrégateur de flux rss en espérant pour vous (c'est plus mon problème après si le logiciel est mal conçu :/) que ça ne fera que tronquer la fin de mon shaarlien (ou pas du tout si votre agrégateur est bien configuré :)).
Voici donc une phrase, sur la ligne suivante je vais y mettre le caractère maudit et à la ligne suivante je conclurai. Si vous n'avez pas de conclusion, vous savez qu'il y a un problème ;) (la solution est expliquée ici en partie dans mon brouillon très moche sur l'unicode et l'utf-8: http://www.olissea.com/doc/?artId=23 )
😒
Voilà, j'espère que tout s'est bien passé pour vous :D
Bonne journée à vous !
Par contre, si mysql est mal configuré (trop souvent le cas), le message se voit tronqué :p
On va donc tester vos agrégateur de flux rss en espérant pour vous (c'est plus mon problème après si le logiciel est mal conçu :/) que ça ne fera que tronquer la fin de mon shaarlien (ou pas du tout si votre agrégateur est bien configuré :)).
Voici donc une phrase, sur la ligne suivante je vais y mettre le caractère maudit et à la ligne suivante je conclurai. Si vous n'avez pas de conclusion, vous savez qu'il y a un problème ;) (la solution est expliquée ici en partie dans mon brouillon très moche sur l'unicode et l'utf-8: http://www.olissea.com/doc/?artId=23 )
😒
Voilà, j'espère que tout s'est bien passé pour vous :D
Bonne journée à vous !
Ahaha x'D Courage ^^
Je me suis tappé la tête contre le mur pendant plusieurs jours avec l'encodage en PHP et même un peu en Python (surtout le 2 qui me casse les noises :o)
Mon site se convertit en UTF-8, yeay !! :DD
Au fait, j'crois que tu n'utilises pas de BDD genre MySQL toi, mais sachez que, en plus de tous les autres trucs qui font chier en PHP vis-à-vis de l'UTF-8 mal géré nativement, MySQL utilise également un encodage à la con de base pour ces communications :/ donc rien à voir avec la façon dont vous stockez vos chaines dans la BDD. Quand vous les récup, il convertit en ISO quelque chose ce con :o (lol) sauf si vous faites la requête SET NAMES utf-8.
Rappel: Utilisez toujours et partout UTF-8. Les problèmes viennent des autres encodages !! Si vous ne prenez pas la bonne habitude de mettre de l'utf-8 partout, vous "risquez" d'en chier lorsque vous voudrez reconvertir en UTF-8 (car c'est un milliard de fois mieux).
Je me suis tappé la tête contre le mur pendant plusieurs jours avec l'encodage en PHP et même un peu en Python (surtout le 2 qui me casse les noises :o)
Mon site se convertit en UTF-8, yeay !! :DD
Au fait, j'crois que tu n'utilises pas de BDD genre MySQL toi, mais sachez que, en plus de tous les autres trucs qui font chier en PHP vis-à-vis de l'UTF-8 mal géré nativement, MySQL utilise également un encodage à la con de base pour ces communications :/ donc rien à voir avec la façon dont vous stockez vos chaines dans la BDD. Quand vous les récup, il convertit en ISO quelque chose ce con :o (lol) sauf si vous faites la requête SET NAMES utf-8.
Rappel: Utilisez toujours et partout UTF-8. Les problèmes viennent des autres encodages !! Si vous ne prenez pas la bonne habitude de mettre de l'utf-8 partout, vous "risquez" d'en chier lorsque vous voudrez reconvertir en UTF-8 (car c'est un milliard de fois mieux).
Comme ça si vous commandez un gâteau d'anniversaire en ligne pour un prénom russe, vous n'aurez pas cette blague.
(Source : http://thedailywtf.com/Articles/Things-Go-Hilariously-Wrong-at-Nuremberg.aspx#Pic-5 )
(Source : http://thedailywtf.com/Articles/Things-Go-Hilariously-Wrong-at-Nuremberg.aspx#Pic-5 )
Tiens, je connaissais pas, c'est marrant cette notation :)
print('\N{left-pointing double angle quotation mark}') # Output: «
Et pour avoir le nom d'un caractère :
import unicodedata
print(unicodedata.name('«')) # Output: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
print('\N{left-pointing double angle quotation mark}') # Output: «
Et pour avoir le nom d'un caractère :
import unicodedata
print(unicodedata.name('«')) # Output: LEFT-POINTING DOUBLE ANGLE QUOTATION MARK