[ nezki @ 17.12.2008. 11:23 ] @
Radim pretragu baze u kojoj mi je sav sadrzaj u cirilici, i sada kada unesem neki termin za pretragu pretraga mi je case sensitive, a potrebno mi je suprotno.
Probao sam da resim taj problem sto sam probao sa ovakvim upitom
SELECT * FROM tabela WHERE LCASE(sadrzaj) LIKE LCASE('%Termin za pretragu%') ali LCASE ne radi kada je cirilica u pitanju
Cak i kada sam probao da vratim neki sadrzaj iz baze na pr. SELECT LCASE(sadrzaj) FROM tabela
Vraceni podaci nisu bili samo mala slova, sto znaci da ove funkcije ucase i upper i lcase i lower ne rade za utf-8 karakter set
Probao sam da stavim karakter set za tebelu i utf8 i latin1 ali nece da radi pa nece.
Pomagajte
[ bogdan.kecman @ 17.12.2008. 12:00 ] @
Generalni odgovor, ako sve radis kako treba (polje u tabeli je utf8, kacis se iz klijenta i setujes konekciju kao utf8) da promenis collation sa utf8_bin na neki drugi (utf8_unicode_ci na primer) i radice ti case insensitive pretraga, sa utf_bin collation-om pretraga je case sensitive.


Kako ti izgleda tabela, tj. koji ti je charset za polje po kom radis pretragu, i koji ti je collation za isto to polje?
Kako se kacis na bazu (php/jdbc/capi/c++api/odbc/...)?

Sta je cesta greska, ako na primer koristis PHP, napravis tabelu polje u tabeli koje je UTF8, na svojoj html strani uzimas input koji je UTF8, upisujes to u bazu i citas iz baze i sve "deluje" ok. Sta je problem, vrlo cesto nije ... primer:

Code:

<?php
  mysql_connect("localhost", "pera", "pera");
  mysql_use_db("test");
  mysql_query("insert into pera values(1,2,3,'".$_GET['nesto']."')");
?>


sve i ako je cetvrti atribut u tabeli pera utf8 u njega ce biti upisana brljotina koja ce posle biti prikazana ok kada je procitas, ali je i dalje brljotina ... zasto?

$_GET["nesto"] u sebi sadrzi UTF8 string .. super . recimo da je to 3 slova cirilicom. Cirilica u utf8 zauzima 2 bajta po slovu, posto php konektor uvek pravi konekciju prema bazi kao latin1, desava se sledece, tih 6 bajtova ce php konektor poslati mysql-u kao 6 latin1 karaktera i to 3 sedmobitna i 3 osmobitna, mysql ce onda tih 6 latin1 karaktera snimiti kao 6 UTF8 karaktera u polje od kojih ce svaki zauzeti 3 bajta. Dakle, tvoja 3 cirilicna karaktera su u polju zauzela 18 bajtova a mysql ih vidi kao 6 karaktera. Ti kada to procitas to "izgleda" ok u html-u posto ti mysql vrati onih 6 karaktera koje ti prikazes, browser ih interpretira kao utf8 (posto mu to stoji u hederu) i ti to "vidis ok" ali to nije ok!!!

kako da resis problem ...

Code:

<?php
  mysql_connect("localhost", "pera", "pera");
  mysql_use_db("test");
  mysql_query("SET NAMES utf8"); // OVO KAZE MYSQL-u DA CE PHP DA SALJE UTF8 a ne LATIN1 karaktere
  mysql_query("insert into pera values(1,2,3,'".$_GET['nesto']."')");
?>


sada vise nemas problem i kada upisujes podatke i citas podatke saljes ih i primas kako treba, 3 cirilicna karaktera ce u bazi uzeti samo 9 bajtova (mysql za svaki utf8 karakter trosi uvek 3 bajta), mysql ce upisanu vrednost videti kao 3 a ne kao 6 slova i mocice da koristi collation da ih pravilno sortira, poredi i slicno...

ono sto je "veliki" problem je ako ti imas bazu koja je napunjena pogresno (dakle nisi imao set names=utf8 i app je tako radio godinu dana), sada ce dodavanje ovoga set names da napravi totalni dzumbus, stare zapise ces citati kao brljotine i slicno ... u ovom slucaju prvo moras da napises mali app koji ce da iskopira tabele (jedan po jedan red) u nove tabele i uradi retranskribciju polja koja su pogresno uneta u pravilno uneta polja, pobijes stare tabele i nastavis da radis sa novim tabelama ...

Sve ovo isto moze da se desi i sa drugim konektorima, razlika je samo u nacinu kako se setuje charset konekcije, u JDBC-u se to setuje u uri-u konekcije na primer...

Ne znam koliko ti ovo pomaze, ako si korektno unosio podatke u bazu, promena collation-a iz utf8_bin u bilo koji drugi bi trebala da resi problem, ako si pogresno unosio podatke, imas primer kako se to radi u php-u, ako si radio u necemu drugom nadji kako se setuje charset za konekciju, ako ne nadjes, tu smo pa pitaj. ako si ti menjao charset za polje iz utf8 u latin1 i podaci su ostali "ok" znaci da nisi punio podatke kako treba, da ti se cirilica nalazi u tabeli kao validan utf8 posle konverzije polja u latin1 video bi samo gomilu upitnika.

EDIT: zakacio sam ti primer php-a kako to sljaka

[Ovu poruku je menjao bogdan.kecman dana 17.12.2008. u 13:36 GMT+1]
[ bogdan.kecman @ 17.12.2008. 12:17 ] @
da, LCASE i UCASE ce normalno raditi kada u bazi budu "ok" podaci
[ nezki @ 17.12.2008. 13:37 ] @
Faco ne znam sta bih ti rekao.
HVALA ti puno. Rešavao sam ovaj problem dugo vremena i da nije bilo tebe nikada ne bih rešio. Guglao sam ali svuda piše da treba da radi ali nema objašnjenje ako ne radi.
HVALA TI!
[ nezki @ 17.12.2008. 13:39 ] @
vidiš da su i ovi sa ESa uveli automatsko prevođenje u latinicu
Mogli bi da ostave ovde taj translator
[ bogdan.kecman @ 17.12.2008. 14:28 ] @
Citat:
nezki: vidiš da su i ovi sa ESa uveli automatsko prevođenje u latinicu
Mogli bi da ostave ovde taj translator


ne znam sta ti znaci "automatsko prevodjenje u latilinicu" :) ali koliko ja vidim forum sw radi ok (sa svojim falinkama poput "usability" problema koji mi ne dozvoljava da vidim koje teme imaju poruke koje nisam procitao)...

vecina forum sw-a ne koristi utf uopste vec karaktere koji ne spadaju u latin1 snimaju kao html kodove (&#nnn; ), to je za anglikansko podrucje ok posto se samo tu i tamo po negde pojavi neki "strani" karakter, za forum gde je to malo cesce (poput pisanja postova cirilicom) to povecava storage consumption (umesto 3 bajta po cirilicnom karakteru kao utf8 dobijes 6 bajtova za html kod string) duplo. Ideju nemam kako se tu radi pretraga sa takvim kodovima koja je "case insensitive" ali znam da neki forumi posebno prave indexe (svoje, ne koriste bazu za pretragu) tako sto sve te karaktere u startu prebacuju u lower case....

no odosmo od teme ... to ti sada radi .. znas za ubuduce sta i kako .... nadam se samo da si na problem naleteo pre nego si bazu vec napunio smecem tako da neces imati problem sa konverzijom smeca u utf8. Obrati samo paznju da iako cirilica zauzima 2 bajta po utf8 standardu, mysql *uvek* koristi 3 bajta za utf8 karakter (ovo ti je bitno zato sto su limiti u mysql-u vezani za bajtove a ne za karaktere tako da key moze da bude dugacak max 1000 bajtova pa ne mozes da stavis 2 polja od po 200 utf8 karaktera u jedan key na primer)
[ Shinhan @ 18.12.2008. 07:27 ] @
Citat:
bogdan.kecman:
vecina forum sw-a ne koristi utf uopste vec karaktere koji ne spadaju u latin1 snimaju kao html kodove (&#nnn; ), to je za anglikansko podrucje ok posto se samo tu i tamo po negde pojavi neki "strani" karakter, za forum gde je to malo cesce (poput pisanja postova cirilicom) to povecava storage consumption (umesto 3 bajta po cirilicnom karakteru kao utf8 dobijes 6 bajtova za html kod string) duplo.


Pre nego što smo prešli na UTF-8, to se i kod nas dešavalo. Sve izgleda ok, ali odjednom jedan ćirilični članak je bio isečen na pola. Kad sam pogledao source, ono sva slova su napisana sa &#nnn; kodovima, i TEXT polje nije bilo dovoljno veliko za to. Taj konkretan problem smo rešili menjanjem polja na MEDIUMTEXT, ali jedino trajno rešenje je ceo sajt na UTF-8.

Btw, kakva je razlika između utf8_general_ci i utf8_slovenian_ci? Ja uvek koristim slovenian, a drugi koriste general.
[ bogdan.kecman @ 18.12.2008. 14:38 ] @
Citat:
Btw, kakva je razlika između utf8_general_ci i utf8_slovenian_ci? Ja uvek koristim slovenian, a drugi koriste general.


ja trosim utf8_unicode_ci :)

Citat:

MySQL implements the xxx_unicode_ci collations according to the Unicode Collation Algorithm (UCA) described at http://www.unicode.org/reports/tr10/. The collation uses the version-4.0.0 UCA weight keys: http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt. Currently, the xxx_unicode_ci collations have only partial support for the Unicode Collation Algorithm. Some characters are not supported yet. Also, combining marks are not fully supported. This affects primarily Vietnamese, Yoruba, and some smaller languages such as Navajo. The following discussion uses utf8_unicode_ci for concreteness.


za razlike izmedju kolacija pogledaj:
http://www.collation-charts.org/mysql60/by-charset.html#utf8

tj. http://www.collation-charts.or...ysql604.utf8_slovenian_ci.html i http://www.collation-charts.or....utf8_general_ci.american.html

kako se pravi nova pogledaj ovo: http://forge.mysql.com/wiki/How_to_Add_a_Collation

nadam se da pomaze.
[ nezki @ 20.12.2008. 12:05 ] @
E sada imam drugi problem
sada hocu da u tekstovima u kojima se pronadje trazeni termin da se taj termin podeblja, ali opet mi ne radi jer je cirilica u pitanju:
pokusao sam ovako da uradim to ali ne radi mi
str_ireplace($trazeni_termin, "<b>".$trazeni_termin."</b>", $tekst);
$tekst=preg_replace("~$trezeni_termin~iUs", "<b>$0</b>", $tekst);

Kada je u pitanju latinica radi, ali sa cirilicom ne radi.
[ bogdan.kecman @ 20.12.2008. 15:00 ] @
to ti je sada to php-a, nema veze sa mysql-om ...

koristi multibyte string funkcije da bi korektno radio sa utf stringovima: http://www.php.net/manual/en/ref.mbstring.php

[ nezki @ 21.12.2008. 10:20 ] @
Ok. Prebacicu temu u php. Nisam uspeo da resim sa mb_string funkcijama.
mb_ereg_ireplace($trazeni_termin,"<b>$trazeni_termin</b>",$tekst);
cak sam nasao i jednu ok funkciju koja
Code:

function mb_str_ireplace($co, $naCo, $wCzym)
{
    $wCzymM = mb_strtolower($wCzym);
    $coM    = mb_strtolower($co);
    $offset = 0;
   
    while(($poz = mb_strpos($wCzymM, $coM, $offset)) !== false)
    {
        $offset = $poz + mb_strlen($naCo);
        $wCzym = mb_substr($wCzym, 0, $poz). $naCo .mb_substr($wCzym, $poz+mb_strlen($co));
        $wCzymM = mb_strtolower($wCzym);
    }
   
    return $wCzym;
}

koja bi trebala da radi ali cim uradim mb_strtolower($tekst) dobijem samo znakove pitanja, mislim da je nesto do encodinga opet.
[ bogdan.kecman @ 21.12.2008. 11:07 ] @
nisam 100 godina trosio php ali mislim da moras da setujes interni enkoding da bi mb funkcije radile kako treba:
http://www.php.net/manual/en/function.mb-internal-encoding.php

Code:

<?php
    mb_internal_encoding("UTF-8");
    mb_http_output( "UTF-8" );
    ob_start("mb_output_handler");
    echo $_GET["x"]."   ".mb_strtolower($_GET["x"]);
?>


kod mene radi .. dal treba nesto posebno da se tu doda ... ne znam
[ misk0 @ 21.12.2008. 11:08 ] @
Otvori temu u PHP forumu za to i prebacicu ti ove zadnje 3 poruke jer su totalni offtopic na ovoj temi.