2013-02-24 5 views
5

Ich habe ein Problem mit UTF-8 und mb_strtoupper.PHP: mb_strtoupper funktioniert nicht

mb_internal_encoding('UTF-8'); 
$guesstitlestring='Le Courrier de Sáint-Hyácinthe'; 

$encoding=mb_detect_encoding($guesstitlestring); 
if ($encoding!=='UTF-8') $guesstitlestring=mb_convert_encoding($guesstitlestring,'UTF-8',$encoding); 

echo "DEBUG1 $guesstitlestring\n"; 
$guesstitlestring=mb_strtoupper($guesstitlestring); 
echo "DEBUG2 $guesstitlestring\n"; 

Ergebnis:

DEBUG1 Le Courrier de Sáint-Hyácinthe 
DEBUG2 LE COURRIER DE S?INT-HY?CINTHE 

Ich verstehe nicht, warum dies geschieht? Ich versuche so vorsichtig wie möglich mit der Codierung umzugehen. Die Zeichenfolge wird zuerst als UTF-8 angegeben, überprüft und möglicherweise in UTF-8 konvertiert. Es ist ein Albtraum!

UPDATE

Also habe ich herausgefunden, dass dies durch eine Kombination meiner Eingabe der Argumente über die Konsole und die Argumente des Rückwegs aus der Konsole verursacht wurde. So waren sie sowohl auf dem Hinweg als auch auf dem Hinweg verstümmelt. Die Lösung besteht darin, keines der Argumente auf diese Weise einzugeben oder die Argumente auf diese Weise zu erhalten.

Vielen Dank für Ihre Hilfe bei der Lösung dieses Problems!

+0

Es ist an der Konsole hallte zu werden, aber es in der Konsole offensichtlich tut Anzeige, weil die Bindestriche in debug1 sind. – Alasdair

+1

Wie lautet die Codierung Ihrer .php-Datei? Versuchen Sie, es in utf-8 ohne BOM zu konvertieren. – Hast

+0

... mh, versuche setlocale hinzuzufügen (LC_ALL, 'en_US.UTF-8'); an der Spitze – Federkun

Antwort

5

Anstelle von strtoupper()/mb_strtoupper() verwenden Sie mb_convert_case(), da die Umwandlung von Großbuchstaben bei verschiedenen Codierungen sehr schwierig ist. Stellen Sie außerdem sicher, dass Ihre Zeichenfolge IS UTF-8 ist.

$content = 'Le Courrier de Sáint-Hyácinthe'; 

mb_internal_encoding('UTF-8'); 
if(!mb_check_encoding($content, 'UTF-8') 
    OR !($content === mb_convert_encoding(mb_convert_encoding($content, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32'))) { 

    $content = mb_convert_encoding($content, 'UTF-8'); 
} 

// LE COURRIER DE SÁINT-HYÁCINTHE 
echo mb_convert_case($content, MB_CASE_UPPER, "UTF-8"); 

Arbeitsbeispiel: http://3v4l.org/enEfm#v443

Siehe auch mein Kommentar auf der PHP-Website über den Konverter: http://www.php.net/manual/function.utf8-encode.php#102382

+0

Warum ist das 'á' in der Ausgabe in Kleinbuchstaben? – Hast

+0

@Hast Ich bin mir nicht sicher. Vielleicht nur bei der französischen Zeichencodierung existiert der Großbuchstabe á? – powtac

+0

Ich habe nur ein Beispiel aus der Frage in meiner Konsole und es hallte: "DEBUG2 LE COURRIER DE SÁINT-HYÁCINTHE" – Hast

2

Es funktioniert für mich, aber nur, wenn die PHP-Datei selbst wird als UTF gespeichert -8 und wenn das Terminal, in dem ich mich befinde, UTF-8 erwartet. Ich denke, was für Sie passiert ist, dass die Datei als ISO-8859-1 gespeichert wird und Ihr Terminal ISO-8859-1 erwartet.

Erstens, mb_detect_encodingfunktioniert nicht wirklich für diese Zeichenfolge. Auch wenn die PHP-Datei nicht UTF-8 ist, wird sie trotzdem als UTF-8 angezeigt.

Wenn Sie die Kleinbuchstaben-Zeichenfolge drucken, druckt es ISO-8859-1-Zeichen und Ihr Terminal zeigt sie einwandfrei an. Wenn Sie dann mit UTF-8 in Großbuchstaben umwandeln, wird es beschädigt.

Ich habe zwei Versionen dieser Datei erstellt. Ich habe es mit meinem Texteditor in ISO-8859-1 als iso-8859-1.php gespeichert. Dann habe ich iconv die gesamte Datei in UTF-8 zu konvertieren und gespeichert als utf-8.php

iconv iso-8859-1.php --from iso-8859-1 --to UTF-8 > utf-8.php 

ich eine Linie hinzugefügt, um das Ergebnis der Codierung zu drucken, die Renditen mb_detect_encoding.

$ file iso-8859-1.php 
iso-8859-1.php: PHP script, ISO-8859 text 

$ php iso-8859-1.php 
ENCODING: UTF-8 
DEBUG1 Le Courrier de S�int-Hy�cinthe 
DEBUG2 LE COURRIER DE S?INT-HY?CINTHE 

$ file utf-8.php 
utf-8.php: PHP script, UTF-8 Unicode text 

$ php utf-8.php 
ENCODING: UTF-8 
DEBUG1 Le Courrier de Sáint-Hyácinthe 
DEBUG2 LE COURRIER DE SÁINT-HYÁCINTHE 

Mein Terminal erwartet eigentlich UTF-8-Text, also wenn ich ISO-8859-1-Text drucke, wird es verstümmelt. Alles funktioniert korrekt, wenn die Datei als utf-8 gespeichert wird und das Terminal utf-8 erwartet.

+1

weil mb_detect_encoding nicht funktioniert, überprüfe ich, ob der codierte und wieder decodierte String immer noch der ursprüngliche String in meiner Antwort ist: http://Stackoverflow.com/a/15051401/22470 – powtac

+0

OK. Aber ich kann das nicht tun, weil die Zeichenfolge als Argument in das PHP-Skript auf der Konsole gegeben wird. Also muss ich es irgendwie aus dem PHP-Skript in UTF-8 erzwingen. – Alasdair

+0

Siehe meine Antwort, ich konvertiere die Zeichenfolge in UTF-8, egal was die Eingabezeichenfolge ist ... – powtac

2

Eigentlich, was hier funktioniert, ist einfach

<?php 
mb_internal_encoding('UTF-8'); 

$x='Le Courrier de Sáint-Hyácinthe'; 
echo mb_strtoupper($x) . "\n"; 

Ausgänge

LE COURRIER DE SÁINT-HYÁCINTHE 

hier direkt, aber vielleicht in Ihrem Fall funktioniert haben Sie utf8_encode hinzuzufügen:

$x = utf8_encode('Le Courrier de Sáint-Hyácinthe'); 

- -

Eine Alternative, die hier ohne MB arbeitet,

<?php 
echo strtoupper(str_replace('á', 'Á', 'Le Courrier de Sáint-Hyácinthe')); 
+0

Dies funktioniert nur, wenn Sie eine richtige UTF-8-Eingabezeichenfolge haben. – powtac

+0

Bearbeitete die Antwort. –