Gemischtes urldecode

Hallo,

ich habe einen größeren Datenbestand, in dem verschiedene Formen des URLencode verwandt wurden: Das ö ist mal %C3%B6, mal %F6. Wie kann ich das unterscheiden bzw. decodieren?

Vielen Dank
JayKay

Hallo

ich habe einen größeren Datenbestand, in dem verschiedene
Formen des URLencode verwandt wurden:

Sowas ist immer ärgerlich, insbesondere wenn man die Umwandlung nicht mitgespeichert hat. Beim nächsten Mal: Wenn man sowas ändert, dann diese Änderung auf alle vorhandenen datensätze übernehmen.

Das ö ist mal %C3%B6,
mal %F6. Wie kann ich das unterscheiden bzw. decodieren?

Das eine ist UTF8 und das andere scheinbar ISO-8859-1

Das geht, auch wenn ich vorsichtig wäre insbesondere mit dem Euro-Zeichen. http://de1.php.net/manual/de/function.iconv.php

function decodeMyStuff($input)
{
 //erstmal das eigentliche decoding
 $input=rawurldecode($input);
 //jetzt noch UTF-8 dekodieren, liefert ein false, falls nicht UTF8 und wirft ein Notice 
 $output=@iconv("UTF-8", "ISO-8859-1",$input );
 //Fallunterscheidung
 if(!$output) 
 return $input; 
 else 
 return $output;
}

echo "UTF8: ";
echo decodeMyStuff("%C3%B6");
echo "
ISO-8859-1: ";
echo decodeMyStuff("%F6");

liefert
UTF8: ö
ISO-8859-1: ö

Günther.

Stern? Bitte gern.

Funktioniert leider noch nicht
Hallo Guenther,

vielen, vielen Dank für Deine Unterstützung.

Beim nächsten Mal: Wenn man sowas ändert, dann diese Änderung auf alle
vorhandenen datensätze übernehmen.

Ohja, das wird auf jeden Fall gemacht. :wink:

function decodeMyStuff($input)
{
//erstmal das eigentliche decoding
$input=rawurldecode($input);
//jetzt noch UTF-8 dekodieren, liefert ein false, falls nicht
UTF8 und wirft ein Notice
$output=@iconv(„UTF-8“, „ISO-8859-1“,$input );
//Fallunterscheidung
if(!$output)
return $input;
else
return $output;
}

echo „UTF8: „;
echo decodeMyStuff(“%C3%B6“);
echo "
ISO-8859-1: „;
echo decodeMyStuff(“%F6");

liefert
UTF8: ö
ISO-8859-1: ö

Leider jedoch gibt Deine Funktion bei mir immer nur � zurück. Woran kann das liegen?

Stern? Bitte gern.

Aber natürlich! :smile:

JK

Ergänzung: Zeichenkodierung im Browser
Hallo Günther,

ich nochmal: Ich habe jetzt die Zeichenkodierung im Firefox umgestellt von vorher Unicode auf jetzt „Westlich“ und nun funktioniert Deine Funktion (nochmals besten Dank dafür). Das PHP-Script benötige ich aber, um die Daten in einer MySQL-Db zu korrigieren, daher muß ich nun schauen, wie die mithilfe der Funktion umgewandelten Strings in die Db geschrieben werden.

Hoffentlich klappts.

Viele Grüße
JK

Das
PHP-Script benötige ich aber, um die Daten in einer MySQL-Db
zu korrigieren, daher muß ich nun schauen, wie die mithilfe
der Funktion umgewandelten Strings in die Db geschrieben
werden.

Du kannst iconv() auch umdrehen und am Ende wieder in UTF-8 umwandeln lassen. Wichtig ist, dass du erstmal dein ö richtig auflöst. Danach kannst du das dann konvertieren wohin du es brauchst.

Viel Erfolg,

Günther

1 Like

Stimmt, einfach zurück. Jetzt klappt’s.
Hallo Günther,

Du kannst iconv() auch umdrehen und am Ende wieder in UTF-8
umwandeln lassen. Wichtig ist, dass du erstmal dein ö richtig
auflöst. Danach kannst du das dann konvertieren wohin du es
brauchst.

Eigentlich logisch. Ich hatte vorhin scho so viel mit derartigen Funktionen erfolglos herumoperiert, daß ich diesen einfachen Weg schon gar nicht mehr in Betracht gezogen hatte. Es scheint zu funktionieren.

Nochmals den allerbesten Dank und noch ein * :smile:
JK

Neiiiiiin… Doch noch ein Fehler

function decodeMyStuff($input)
{
//erstmal das eigentliche decoding
$input=rawurldecode($input);
//jetzt noch UTF-8 dekodieren, liefert ein false, falls nicht
UTF8 und wirft ein Notice
$output=@iconv(„UTF-8“, „ISO-8859-1“,$input );
//Fallunterscheidung
if(!$output)
return $input;
else
return $output;
}

echo „UTF8: „;
echo decodeMyStuff(“%C3%B6“);
echo "
ISO-8859-1: „;
echo decodeMyStuff(“%F6");

liefert
UTF8: ö
ISO-8859-1: ö

Aber:
decodeMyStuff(„Fr%F6hlich“) liefert „Fr“, der Rest wird abgeschnitten. Mit nachfolgenden Zeichen tut das nicht. Hiiiilfe …

JK

Hallo,

<?php $input = "Fr%F6hlich";
$input=rawurldecode($input); echo $input; /\* Fröhlich \*/ $output=@iconv("UTF-8", "ISO-8859-1",$input ); echo $output; /\* Fr \*/ $output=@iconv("ISO-8859-1", "ISO-8859-1",$input ); echo $output; /\* Fröhlich \*/ $output=@iconv("ISO-8859-1", "UTF-8",$input ); echo $output; /\* Fröhlich \*/ ?\> Ich würde glatt sagen das das %... Zeichen ISO in UTF-8 nix erlaubt ist und damit ausgesiebt wird :smile:

Aber:
decodeMyStuff(„Fr%F6hlich“) liefert „Fr“, der Rest wird
abgeschnitten. Mit nachfolgenden Zeichen tut das nicht.

Hm. Ärgerlich.

Also rawurldecode liefert brav Fröhlich und iconv macht es wieder kaputt, weil er eben nur dann false liefert, wenn die Zeichenkette gänzlich unumwandelbar ist.

Dann graben wir tiefer. Wir brauchen also eine Prüfung, ob eine Zeichenkette UTF-8 ist. Eine schnelle Suche liefert das zu Tage:

http://floern.com/webscripting/is-utf8-auf-utf-8-pr%…

Wenn ich das ohne drüber nachzudenken in mein Skript einbaue kriege ich.

//http://floern.com/webscripting/is-utf8-auf-utf-8-pr%C3%BCfen
function is\_utf8($str){
 $strlen = strlen($str);
 for($i=0; $i0xC1) $n = 1; // 110bbbbb (exkl C0-C1)
 elseif(($ord&0xF0)===0xE0) $n = 2; // 1110bbbb
 elseif(($ord&0xF8)===0xF0 && $ordISO-8859-1: ";
echo decodeMyStuff("%F6");
echo " ";
echo "UTF8: ";
echo decodeMyStuff("Fr%C3%B6hlich");
echo "
ISO-8859-1: ";
echo decodeMyStuff("Fr%F6hlich");

liefert
UTF8: ö
ISO-8859-1: ö

UTF8: Fröhlich
ISO-8859-1: Fröhlich

Günther

Stern? Bitte gern.

2 Like

Alternative
Hallo Günther,

function is_utf8($str){
$strlen = strlen($str);
for($i=0; $i0xC1) $n = 1; // 110bbbbb
(exkl C0-C1)
elseif(($ord&0xF0)===0xE0) $n = 2; // 1110bbbb
elseif(($ord&0xF8)===0xF0 && $ord

Das sieht gut aus, werde ich auch noch testen. Vielen Dank :smile: Ich habe inzwischen das hier auf Grundlage Deines ersten Codes gebastelt:

function stringCodeNormalization ($input) {
 $Dinput = rawurldecode($input);
 $output = @iconv("UTF-8", "ISO-8859-16", $Dinput);

 if (mb\_strlen($Dinput, "UTF8") == mb\_strlen($output, "ISO-8859-1")) {
 $result = @iconv("ISO-8859-1", "UTF-8", $output);
 } else {
 $result = @iconv("ISO-8859-1", "UTF-8", rawurldecode(iconv("UTF-8", "ISO-8859-1", $input)));
 }
 return $result;
}

Was meinst?

Stern? Bitte gern.

Aber selbstverständlich …

Nochmals ganz dollen Dank
JK

Das sieht gut aus, werde ich auch noch testen. Vielen Dank :smile:

Ja, unbedingt. Solche Encodings sind schwer zu bändigen. Da gibt es sicher hunderte von Fehlermöglichkeiten, solche Mixturen sind immer kritisch und immer Ergebnis von Unkenntnis oder schlechter/keiner Planung. Und immer an den Euro denken, der bei ISO-8859-1 nicht dabei ist.

Ich habe inzwischen das hier auf Grundlage Deines ersten Codes
gebastelt:

function stringCodeNormalization ($input) {
$Dinput = rawurldecode($input);
$output = @iconv(„UTF-8“, „ISO-8859-16“, $Dinput);

if (mb_strlen($Dinput, „UTF8“) == mb_strlen($output,
„ISO-8859-1“)) {
$result = @iconv(„ISO-8859-1“, „UTF-8“, $output);
} else {
$result = @iconv(„ISO-8859-1“, „UTF-8“,
rawurldecode(iconv(„UTF-8“, „ISO-8859-1“, $input)));
}
return $result;
}

Was meinst?

Bin ich nicht so begeistert, da du den gleichen Fehler machst wie ich gestern. Du gehst aufgrund von sehr begrenzten Testfällen von irgendwelchen Annahmen aus, die mit hoher Sicherheit zu unerwünschten Seiteneffekten führen.

Es ist grundsätzlich besser, auf die relevanten Eigenschaften zu prüfen als auf Ergebnisse von Weiterbehandlungen. Natürlich weiß ich nicht, ob dieser Codeschnipsel den ich fand da besser ist, aber er setzt auf jeden Fall das tragfähigere Konzept um.

Nochmals ganz dollen Dank

Klar, startpage.com war mein Freund.

1 Like

Ich werde es testen
Salu Günther,

nochmals ganz vielen Dank für Deine Ausdauer und Hilfebereitschaft. :smile:

Bin ich nicht so begeistert, da du den gleichen Fehler machst
wie ich gestern. Du gehst aufgrund von sehr begrenzten
Testfällen von irgendwelchen Annahmen aus, die mit hoher
Sicherheit zu unerwünschten Seiteneffekten führen.

Es ist grundsätzlich besser, auf die relevanten Eigenschaften
zu prüfen als auf Ergebnisse von Weiterbehandlungen. Natürlich
weiß ich nicht, ob dieser Codeschnipsel den ich fand da besser
ist, aber er setzt auf jeden Fall das tragfähigere Konzept um.

Hmm, grundsätzlich verstehe ich Dich schon. Doch um das Script tatsächlich als zuverlässiger einstufen zu können, müßte ich die Austausche der Funktion genauer kennen. Zudem hat das Script im ersten Anlauf bei mir nicht funktioniert. Aber ich werde es weitertesten.

Klar, startpage.com war mein Freund.

Kuhl, kannte ich noch gar nicht. Für mich viel wichtiger als die Datensammelisolation ist hier die direkte Erreichbarkeit der Funktionen Sprache und Zeitraum wählen. Google hat das ja jetzt so versteckt, daß man drei gezielte Klicks braucht, statt einem. In Google Maps wurde der Streckenmesser entfernt und überhaupt: Google räumt ganz viele tolle Funktionen aus. Da kommt startpage.com gerade recht. Dafür und für all Deine Hilfe gerne noch ein Sternchen :smile:

Erst mal ein schönes Wochenende
JK

Hmm, grundsätzlich verstehe ich Dich schon. Doch um das Script
tatsächlich als zuverlässiger einstufen zu können, müßte ich
die Austausche der Funktion genauer kennen. Zudem hat das
Script im ersten Anlauf bei mir nicht funktioniert. Aber ich
werde es weitertesten.

Vorschlag: Lass doch einfach sowohl deine als auch meine Funktion parallel auf alle Datenbankeinträge laufen und vergleiche die Ergebnisse. Wenn etwas unterschiedlich ist, dass gibst du dir das aus und kannst dann auf Fehlersuche gehen.

Wie kritisch sind denn diese Daten und was, wenn mal einzelne Datensätze nicht stimmen?

Günther