Autor Zpráva
lionel messi
Profil
Zdravím,

narazil som na pomerne veľký problém pri používaní zmienenej funkcie iconv. Text v UTF-8 nutne potrebujem prekódovať do Windows-1250. Funguje všetko, okrem pre mňa nevysvetliteľných problémov so znakom „ň“. V UTF-8 sa zobrazuje ako sekvencia „Ĺ?“, čo pri výstupe vo Windows-1250 zobrazuje ako „�“. Pozoruhodné je správanie sa funkcie v opačnej situácii, teda pri prevode z Windows-1250 do UTF-8, kde sa zobrazí iba poznámka:
Notice:  iconv(): Detected an illegal character in input string…

Netuším, prečo sa tak deje a ako sa s týmto problémom vysporiadať a tak by som rád poprosil o radu skúsenejších kolegov.

V prípade, že uvedená situácia nie je riešiteľná, by som sa chcel opýtať, ako je možné „zjednotiť“ kódovanie v DB v rámci jedného stĺpca. Kódovanie stĺpca mám totiž Windows-1250, novšie dáta sú uložené v tomto kódovaní a staršie nedopatrením v UTF-8 (čo je príčinou použitia funkcie iconv v PHP). Kódovanie záznamov dokážem spoľahlivo rozlíšiť podľa primárneho kľúča, prípadne stĺpca obsahujúceho dátum. Bolo by možné vytvoriť SQL príkaz, ktorý by zachoval kódovanie jednej časti (je úplne jedno, ktorej) a prepísal druhú do zodpovedajúceho kódovania?

Ďakujem veľmi pekne za každý námet.
Zechy
Profil
V dokumentaci je v examples pro iconv() používáno //TRANSLIT a //IGNORE na speciální znak, bez použití těchto dvou to končí právě tímhle noticem. V komentářích někdo i tímhle způsobem převádí text "Žluťoučký kůň".
lionel messi
Profil
Zechy:
V dokumentaci je v examples pro iconv() používáno //TRANSLIT a //IGNORE na speciální znak, bez použití těchto dvou to končí právě tímhle noticem.

Vďaka za nasmerovanie, ale problém pretrváva.

setlocale(LC_CTYPE, "cs_CZ"); //mala by tu byť nastavená slovenčina, ponechávam zatiaľ bokom
echo iconv("utf-8", "windows-1250//TRANSLIT", "ÄŚerešĹ?a");
echo iconv("windows-1250", "utf-8//TRANSLIT", "ň");

Uvedený kód vypíše:
Čereš�?a
Notice: … //ako v [#1]

//IGNORE nameisto //TRANSLIT sa správa bez najmenšej zmeny úplne rovnako.

Podarilo sa mi nájsť ešte túto starú diskusiu: Čo s písmenom "ň"..., jej obsah mi však nepomôže, pri spojení s db nastavujem kódovanie správne.
Keeehi
Profil
S kódováním jsou vždy jen problémy. Existuje však řešení které už dlouhou dobu úspěšně používám. Vždy, všude, bez výjimky používat jen jedno. Teoreticky si můžeš vybrat jaké chceš, ale prakticky je jediná správná volba - utf8. Problémy pak mohou vznikat jen na krajích kde se může stát že jsi nucen komunikovat s někým, kdo se rozhodl, že chce všechny ostatní vidět v pekle a nepoužívá utf8. To si pak chvíli zanadáváš ale jinak na problémy nenearazíš.
lionel messi
Profil
Keeehi:
Vždy, všude, bez výjimky používat jen jedno [kódování].
Sám som sa nad niečím podobným zamýšľal. Tým sa však dostávame k druhej časti mojej otázky [#1]:

ako je možné ‚zjednotiť‘ kódovanie v DB v rámci jedného stĺpca. Kódovanie stĺpca mám totiž Windows-1250, novšie dáta sú uložené v tomto kódovaní a staršie nedopatrením v UTF-8 (čo je príčinou použitia funkcie iconv v PHP). Kódovanie záznamov dokážem spoľahlivo rozlíšiť podľa primárneho kľúča, prípadne stĺpca obsahujúceho dátum. Bolo by možné vytvoriť SQL príkaz, ktorý by zachoval kódovanie jednej časti (je úplne jedno, ktorej) a prepísal druhú do zodpovedajúceho kódovania?

Žiadne použiteľné riešenie mi zatiaľ nenapadlo. Dáta uložené v db v dvojakom kódovaní som, bohužiaľ, „zdedil“ po svojom predchodcovi (a z každého druhu je zhruba 250 záznamov).
juriad
Profil
lionel messi:
vytvoř si novou tabulku daného kódování, přesyp do ní data pomocí INSERT INTO ... SELECT ... FROM ... WHERE ... a potom jí zkonvertuj. Až budeš mít dvě nové tabulky funkční, sloučíš jejich záznamy dohromady.
lionel messi
Profil
juriad:
Veľmi pekne ďakujem za odpoveď, v najbližších dňoch sa na to pozriem.
Jan Tvrdík
Profil
lionel messi:
Ještě zpátky k tomu iconv – mělo by to fungovat. Zkus schválně spustit
echo bin2hex(iconv("windows-1250", "utf-8", "\xF2")), "<br>\n";
echo bin2hex(iconv("utf-8", "windows-1250", "\xC5\x88")), "<br>\n";
Mělo by to vypsat c588 a f2.

Pokud ne, tak si vypiš
echo ICONV_IMPL . "(" . ICONV_VERSION . ")";

Pokud ano, tak uprav výše uvedený skript na:
$s = "ň";
echo bin2hex($s);
echo iconv("windows-1250", "utf-8", $s);
lionel messi
Profil
juriad:
Bohužiaľ, SQL dotaz uvedený v odkaze
ALTER DATABASE databaza CHARACTER SET cp1250 COLLATE cp1250_bin;
ALTER TABLE tabulka CONVERT TO CHARACTER SET cp1250 COLLATE cp1250_bin;

(úmyselne vymenené utf-8 za cp1250)

síce prebehne úspešne (overené v PMA), ale kódovanie reťazcov zostáva rovnaké (ÄŚerešĹ?a sa nezmení na Čerešňa).

Jan Tvrdík:
Zkus schválně spustit
Výsledok sa zhoduje s očakávaným (správnym) správaním funkcie.

Pokud ano, tak uprav výše uvedený skript na:
Vráti:
c588
Notice:  iconv(): Detected an illegal character in input string…

Prostredný príklad s verziou knižnice vypíše:
glibc(2.13)
Kajman
Profil
lionel messi:
ale kódovanie reťazcov zostáva rovnaké

Ano, ty dva příkazy jen definují výchozí porovnání pro nové tabulky v databázi databaza a nové sloupce v tabulce tabulka.

Je možno převádět i sloupce, ale mám trochu obavu, že to nebude vhodné pro tento případ. Můžete si to zkusit na té zkopírované tabulce, ale osobně bych si u jedné tabulky data jednoduše vyexportoval, udělal konverzi na txt souboru (klidně i ručně dořešil problémy), případně upravil set names v něm a naimportoval do nové tabulky. Když tam budou data dobře, tak udělat update hlavní tabulky podle opravené u těch řádků, které byly špatně.
lionel messi
Profil
Kajman:
Je možno převádět i sloupce, ale mám trochu obavu, že to nebude vhodné pro tento případ.
Napokon to skutočne nefungovalo podľa potreby.

Vyriešené podľa odporúčania v [#10].

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: