Quels sont les facteurs qui rendent PHP Unicode-incompatible?

je suis capable D'utiliser des caractères UTF-8 très bien dans mes scripts.

en fait, il est possible de avoir des noms de variables et des fonctions contiennent des caractères Unicode .

il y a aussi le mb_string extension qui traite des chaînes multi-octets, pourtant dans d'innombrables articles PHP est critiqué pour son manque de support Unicode.

Je ne comprends pas; pourquoi PHP ne dit pas support de l'Unicode?

38
demandé sur Leigh 2009-02-21 02:48:56

7 réponses

lorsque PHP a été lancé il y a plusieurs années, UTF-8 n'était pas vraiment supporté. Nous parlons d'une époque où L'OS non-Unicode comme Windows 98/Me était encore courant et où D'autres grands langages comme Delphi étaient aussi non-Unicode. Toutes les langues n'ont pas été conçues avec Unicode à l'esprit à partir du jour 1, et changer complètement votre langue en Unicode sans casser beaucoup de choses est difficile. Delphi est seulement devenu compatible Unicode il y a un an ou deux par exemple, alors que D'autres langues comme Java ou C# ont été conçus en Unicode dès le premier jour.

donc quand PHP s'est développé et est devenu PHP 3, PHP 4 et maintenant PHP 5, tout simplement personne n'a décidé d'ajouter Unicode. Pourquoi? Probablement pour rester compatible avec les scripts existants ou parce que utf8_de/encode et mb_string existaient déjà et fonctionnaient. Je ne suis pas sûr, mais je crois fermement que cela a quelque chose à voir avec la croissance organique. Les fonctionnalités n'existent pas simplement par défaut, elles doivent être écrites par quelqu'un, et cela n'est tout simplement pas encore arrivé pour PHP.

Edit: Ok, j'ai mal lu la question. La question est: comment les chaînes sont-elles stockées en interne? Si je tape "Währung" ou "Écriture", quel encodage est utilisé pour créer les octets utilisés? Dans le cas de PHP, C'est ASCII avec une page codée. Cela signifie: Si je code la chaîne en utilisant ISO-8859-15 et que vous la décodez avec un peu de codepage chinois, vous obtiendrez des résultats bizarres. L'alternative est dans des langages comme C# ou Java où tout est stocké en Unicode, ce qui signifie: Il n'y a pas de page codée et en théorie, tu ne peux pas tout gâcher. Je recommande article de Joel sur Unicode et les jeux de caractères, mais essentiellement il se résume à: comment sont stockées les chaînes de caractères en interne, et la réponse avec PHP est "pas en Unicode", ce qui signifie que vous devez être très prudent et explicite lors du traitement des chaînes de faire en sorte de toujours garder la chaîne dans le bon encodage pendant l'entrée, le stockage (base de données) et la sortie, qui est très errorprone.

39
répondu Michael Stum 2012-12-11 12:49:14

je crois que c'est en grande partie une difficulté culturelle, pas technique.

quant aux problèmes techniques---et ce n'est pas tout à fait trivial de mettre en œuvre unicode dans un écosystème construit sur les hypothèses que "un caractère égale un octet" ---les développeurs auraient pu copier une grande partie des efforts de java ou de python (ce dernier avec une compatibilité unicode décente et largement fonctionnelle depuis environ 2001), mais ils ne l'ont jamais fait.

quand je lis le fil de discussion attaché à la documentation officielle, actuelle pour la fonction utf8_encode() de php , j'ai un sentiment de vertige.

firstoff, cette fonction est appelée utf8_encode() ; cependant, la documentation indique que la chaîne qu'elle attend est censée être en ISO-8859-1 (a. K. A. latin-1). c'est sooo php, c'est sooo 80s.

la plupart des commentateurs semblent percevoir unicode comme un fardeau. il y a beaucoup de propositions comment convertir des chaînes "de l'inconnu du contenu, la façon de traiter avec s'strings avec un mélange de codages' (wtf?), ou traitant des codépoints qui causent normalement des bris parce qu'ils sont au-delà de la limite de quatre octets par codépoint de cette fonction.

la discussion est centrée sur les correctifs pour se débarrasser des grincements ou pour éviter les parties problématiques du comportement de cette fonction. et ça, pour moi, c'est sooo php: Tout le monde fait juste des corrections, peu de choses sont mises en œuvre d'une manière fondamentalement correcte. si vous pensez que la calomnie, de mon côté, voici quelques bribes:

bien que cela semble casser Allemand Umlaute [äöü] si le document est déjà UTF-8.

(incapacité de comprendre que l'utf-8 n'est pas conçu pour fonctionner lorsqu'il est appliqué deux fois)

regardez la fonction iconv (), qui offre une façon de convertir de 8859 et redouté 1252 en UTF8

(bon point: négligence de l'état de la technique de la part des développeurs php; au lieu de cela, mise en œuvre propre buggy)

utilisation de preg_match pour détecter si utf8_encode est nécessaire [...] à l'exclusion des mères porteuses [...] à l'exclusion des doublures

(suggérant d'effacer silencieusement tout le contenu problématique des chaînes, ne laissant que les choses qui ne cassent pas utf8_encode() ; cela peut rendre les textes illisibles (ou disparaître complètement), mais bon, pas plus messages d'erreur)

pour encoder une chaîne seulement si elle N'est pas encore UTF-8 [...] mb_detect_encoding($s, "UTF-8")

(comme l'a souligné par un autre commentateur , cela ne va pas fonctionner:

$str = 'áéóú'; // ISO-8859-1
mb_detect_encoding($str, 'UTF-8'); // 'UTF-8'
mb_detect_encoding($str, 'UTF-8', true); // false

donc ici nous regardons un bug remplacé par un autre. heureux de chasse. en outre, ce qu'ils semblent proposer ici est de résoudre un problème en utilisant heuristiques (lent, incertain) des moyens qui pourraient et devrait être résolu par des moyens mécaniques (rapides, certains)

utf8_ [encode / decode] va en fait traduire windows-1252 caractères ainsi, pas seulement de/vers ISO-8859-1 comme la documentation dit

(vous ne pouvez jamais compter sur la documentation officielle de php pour être clair ou exhaustif--vous devez toujours lire à travers les années d'expérience des utilisateurs que personne ne sera jamais de retour aux docs)

j'ai travaillé sur une fonction is_utf8 et je voulais la poster ici, en plus des autres j'ai aussi pris en considération le bogue 5000 char

(un correctif pour un problème qui n'existe en grande partie que parce qu'unicode n'est pas correctement implémenté. nous apprenons aussi que non seulement la fonction utf8_encode() abandonne au-delà de 4 octets par point de code, mais qu'elle se casse aussi si le résultat (ou la sortie?) le texte dépasse la limite de 5000 caractères)

je pourrait aller comme ça. vous avez déjà l'idée: à en juger par ce fil, la communauté php n'a tout simplement pas l'air d'être prête à saisir ce que sont les encodages et les jeux de caractères, ce qu'il faut pour construire une infrastructure sonore en général ou, spécifiquement, pour implémenter unicode de manière appropriée. au lieu de ça, ils utilisent leurs échafaudages, leurs cartons, leurs clous et marteaux et continuent à construire ce grand édifice appelé php, jetant leur ruban adhésif à chaque problème ça ne peut pas être défait avec un autre clou. bien sûr, ce bâtiment souffrira de chaque vent qui vient soufflant, comme le caractère occasionnel légal mais inattendu.

voir ce fil actif pendant huit ans n'est pas vraiment rassurant.la situation sera meilleure dans huit ans.

33
répondu flow 2011-04-30 06:11:23

le concept d'un" caractère multibyte " est au cœur du problème.

  1. il fuit un détail d'implémentation: vous devriez être en mesure de travailler avec l'abstraction d'un caractère sans savoir comment les développeurs choisissent de représenter les données - peut-être en fonction de la plate-forme il leur convient de tout représenter comme UTF16 ou UTF32, dans ce cas tout est multibyte, pas que les utilisateurs de l'abstraction de caractère devraient s'en soucier.
  2. c'est un kludge: en plus d'une habitude dépassée de la pensée où nous" savons vraiment " que les chaînes sont des séquences bytes, nous devons maintenant savoir que parfois les octets s'agglutinent ensemble dans des choses connues sous le nom de caractères Unicode, et ont des cas spéciaux partout pour s'en occuper.
  3. c'est comme une souris essayant de manger un éléphant. En encadrant Unicode comme une extension D'ASCII (nous avons des chaînes normales et nous avons mb_strings) il obtient les choses de la mauvaise façon, et obtient raccroché sur les cas spéciaux sont nécessaires pour traiter les personnages avec des grincements drôles qui ont besoin de plus d'un octet. Si vous traitez Unicode comme fournissant un espace abstrait pour n'importe quel caractère dont vous avez besoin, ASCII est accommodé dans cela sans n'importe quel besoin de le traiter comme un cas spécial.
11
répondu 2009-02-26 18:12:26

vous le dites vous-même: pour traiter correctement les chaînes qui contiennent des caractères multi-octets, vous devez utiliser une extension. Oubliez n'importe où pour utiliser les fonctions d'extension au lieu des plus familières "normales", et vos données sont mutilées. La même chose se produit si vous utilisez une bibliothèque tierce qui n'a pas été mise à jour pour utiliser la fonction d'extension partout.

aussi, un certain nombre de encodages extrêmement populaires est encore explicitement pas pris en charge par PHP, probablement parce qu'il est impossible de le faire et de rester compatible vers le bas.

5
répondu Michael Borgwardt 2009-02-21 00:22:18

beaucoup d'extensions communes n'ont pas de support unicode ou (pire) vous "devez savoir" qu'une chaîne contient des séquences unicode/utf-8, comme par exemple XMLReader. Et cela peut faire une grande différence que PHP appelle findfirstfilea ou FindFirstFileW sur win32.

Une autre question (beaucoup plus petite mais étonnamment souvent être la source d'ennui) sont des BOMs que PHP ne reconnaît pas.

3
répondu VolkerK 2009-02-21 00:25:55

beaucoup de fonctions de chaîne de caractères sont simplement des enveloppements minces autour des équivalents de bibliothèque C, qui traitent aussi tout comme une séquence d'octets. Une autre raison est que PHP transporte beaucoup de bagages inutiles de rétrocompatibilité et se retrouve ainsi coincé avec de mauvaises décisions de conception de 3&4.

peut-être qu'avec les namespaces de 5.3 ils auront enfin un moyen d'éliminer les anciennes fonctions.

3
répondu 2009-02-21 00:28:51

ce qu'on entend par "soutien" est "Soutien autochtone". Jetez un oeil à ce pour obtenir des informations détaillées.

2
répondu muratgu 2009-02-21 00:06:29