Avatar billede akyhne Nybegynder
24. januar 2009 - 15:44 Der er 77 kommentarer og
1 løsning

Længde og deling af utf-8 streng

Hej.

Jeg har en streng jeg skal have splittet på en side lavet til utf-8.

Eks: $myText = 'abcæøå';

Med strlen($myText); får jeg at vide der er 10 karakterer.

Hvordan får jeg delt hvert bogstav af $mytext til et array af de 6 bogstaver?
Avatar billede tmi Nybegynder
24. januar 2009 - 15:49 #1
mb_strlen($myText);
Avatar billede majbom Novice
24. januar 2009 - 15:50 #2
$myText['2'] - skulle gerne være "c"...
Avatar billede tmi Nybegynder
24. januar 2009 - 15:51 #3
<?
function mb_str_split($str, $length = 1) {
  if ($length < 1) return FALSE;

  $result = array();

  for ($i = 0; $i < mb_strlen($str); $i += $length) {
    $result[] = mb_substr($str, $i, $length);
  }

  return $result;
}
?>
Avatar billede akyhne Nybegynder
24. januar 2009 - 16:11 #4
Det giver mig a, b, c og en masse firkanter... 9 tegn i alt.
Avatar billede akyhne Nybegynder
24. januar 2009 - 16:16 #5
Det virker med mb_strlen($str,'UTF-8'), men så får jeg Array ( [0] => a [1] => b [2] => c [3] => &#65533; [4] => &#65533; [5] => &#65533; )
Avatar billede akyhne Nybegynder
24. januar 2009 - 16:17 #6
... hvor &#65533; er vist som firkanter...
Avatar billede olebole Juniormester
24. januar 2009 - 16:19 #7
<ole>

"Jeg har en streng jeg skal have splittet på en side lavet til utf-8." >> Hvad mon det betyder?  =)

Hvad returneres, hvis du et sted i dit dokument skriver:
    print mb_internal_encoding();

/mvh
</bole>
Avatar billede olebole Juniormester
24. januar 2009 - 16:20 #8
- og hvad sker der, hvis du udskriver strengen:
    print $myText;
Avatar billede akyhne Nybegynder
24. januar 2009 - 16:22 #9
ISO-8859-1... men alt validerer som utf-8???
Avatar billede akyhne Nybegynder
24. januar 2009 - 16:38 #10
print $myText; uden at gøre noget ved teksten skriver abcæøå, men i sourcen står der æøå (en masse mærkelige å'er hvis I ikke kan se det her)

print_r af teksten efter brug af mb_str_split skriver
Array ( [0] => a [1] => b [2] => c [3] => &#65533; [4] => &#65533; [5] => &#65533; )
Avatar billede tmi Nybegynder
24. januar 2009 - 16:42 #11
Prøv evt
<?
preg_match_all("#.#us", $text, $split);
print_r($split);
?>
Avatar billede olebole Juniormester
24. januar 2009 - 16:49 #12
"ISO-8859-1... men alt validerer som utf-8" >> Det er sort. Hvad mener du? Hvis der udskrives ISO-8859-1, bruger du ISO-8859-1  =)
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:04 #13
Siden er lavet i utf-8 format, validerer som utf-8... hvad mere skal der til?
Avatar billede olebole Juniormester
24. januar 2009 - 17:11 #14
Det har jeg ingen anelse om, da du ikke fortæller, hvad du gør.

"Siden er lavet i utf-8 format, validerer som utf-8" giver ikke megen mening. Hvad betyder det i din verden?
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:16 #15
I min verden betyder det at doc typen siger det er utf-8, at w3 validerer siden som utf-8, og at jeg kan skrive æ,ø,å i sourcen og få dem vist rigtig.
Hvis det ikke er forståelse nok, må du jo belære mig, Ole.
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:18 #16
print mb_internal_encoding(); skriver ISO-8859-1, men det er vel fordi den værdi er sat i php.ini. Men det har vel ikke noget at gøre med hvordan siden fungerer...
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:20 #17
tmi:

preg_match_all("#.#us", $text, $split);
skriver..
Array ( [0] => Array ( [0] => a [1] => b [2] => c [3] => æ [4] => ø [5] => å ) )
... men stadig med mærkelige å tegn.
Avatar billede olebole Juniormester
24. januar 2009 - 17:20 #18
Okay, jamen det er ikke tilfældet. Du skal samtidigt sørge for, at du i din editor gemmer som utf-8 ... ikke som ANSI. Du kan evt. tjekke i Notepad's Gem Som-dialog.

Dernæst skal din DB være sat til at bruge utf-8.

Sidst, men ikke mindst, skal serveren sende dokumenterne som utf-8. Du kan evt. selv sætte en HTTP-header:
    header("Content-Type: text/html; charset=utf-8");
Avatar billede olebole Juniormester
24. januar 2009 - 17:23 #19
Når du validerer på W3C, skal du huske at sætte 'Verbose Output', så du kan se, hvordan serveren sender dine dokumenter:
    http://validator.w3.org/check?uri=http%3A%2F%2Fwww.eksperten.dk%2Fspm%2F861048&charset=(detect+automatically)&doctype=Inline&group=0&ss=1&verbose=1
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:25 #20
Det er gemt som utf-8 uden bom , Db'en bruger utf-8. Headeren havde jeg ikke sat, da jeg ikke mente det var nødvendigt.
Men det giver mig stadig ISO-8859-1...
Avatar billede olebole Juniormester
24. januar 2009 - 17:25 #21
- og husk, at selve valideringen kun handler om din markup-kode.

En valid kode er ikke nødvendigvis god - men en god kode er altid valid  ;o)
Avatar billede olebole Juniormester
24. januar 2009 - 17:25 #22
Har du prøvet at sætte en header?
Avatar billede olebole Juniormester
24. januar 2009 - 17:26 #23
Du kan også prøve:
    mb_internal_encoding("UTF-8");
Avatar billede olebole Juniormester
24. januar 2009 - 17:28 #24
- men det allerbedste vil naturligvis være at ændre din php.ini, hvis du har adgang til den
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:28 #25
Med verbose:

Sorry, I am unable to validate this document because on line 15 it contained one or more bytes that I cannot interpret as utf-8 (in other words, the bytes found are not valid values in the specified Character Encoding). Please check both the content of the file and the character encoding indication.

The error was: utf8 "\xC3" does not map to Unicode

Linie 15 er $result = array(); fra tmi's kode
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:28 #26
php.ini... det har jeg
Avatar billede olebole Juniormester
24. januar 2009 - 17:29 #27
Fejlen på W3C får du, fordi du bruger et ikke-Unicode tegn
Avatar billede olebole Juniormester
24. januar 2009 - 17:30 #28
Linie 15 er $result = array(); fra tmi's kode

Nej, det er linje 15 i din markup-kode - og det kan ikke være PHP  =)
Avatar billede akyhne Nybegynder
24. januar 2009 - 17:41 #29
markup-kode som i...?

Jeg skriver og gemmer i utf-8 formatet.
Avatar billede tmi Nybegynder
24. januar 2009 - 17:49 #30
Men anyway, har jeg ikke givet dig svar på de to spørgsmål det her indlæg faktisk handler om?
Avatar billede akyhne Nybegynder
24. januar 2009 - 18:00 #31
tmi: Din kode gemmer tilsyneladende ikke i utf-8. Derfor kan jeg ikke bruge den, før problemet er løst.
Avatar billede akyhne Nybegynder
24. januar 2009 - 18:09 #32
Det var print_r af $NewText = mb_str_split($msgText); der gav verbose fejlen.
Avatar billede tmi Nybegynder
24. januar 2009 - 18:15 #33
Jo det er lige præcis det min kode gør, hvorfor tror du at du får mærkelige tegn? Det er fordi Unicode (UTF-8) bruger multibytes (derfor funktionerne hedder "mb_") til specielle tegn. I Vesteuropæisk (ISO-8859-1) fylder hvert tegn 1 byte, og strlen giver dig antallet af bytes. Så når du giver funktionen multibytes kan den ikke selv regne ud at det er multibytes og tror derfor at din streng består af mærkelige tegn. Æ, ø og å er alle multibytes i Unicode, derfor giver din streng "abcæøå" længden 9, 1 for a, 1 for b, 1 for c, 2 for æ, 2 for ø og 2 for å. Derfor kan du selvfølgelig heller ikke blande Unicode med Vesteuropæisk tegnsæt i den HTML kode du genererer til brugeren, som du åbenbart prøver at gøre.
Avatar billede tmi Nybegynder
24. januar 2009 - 18:30 #34
Det her vil nok virke til dit formål:

$text = utf8_decode("abc æøå gemt i unicode");
$length = strlen($text);
$chararray = str_split($text);
print_r($chararray);
Avatar billede akyhne Nybegynder
24. januar 2009 - 19:24 #35
Ideen med utf-8 er at du kan bruge din tekst uden at skulle konvertere den i en eller anden form. Så utf8_decode kan jeg ikke bruge til noget, heller ikke tegn som æøå.

Jeg har et forum kørende som bruger utf-8. Der er teksten i php kode ikke en række mærkelige tegn, og alt bliver gemt som det bliver skrevet. Det vil sige at æ gemmes som æ etc.

Det er det samme jeg prøver at opnå. Hvis teksten skal vises med mærkelige tegn, er der overhovedet ingen ide i at bruge utf-8!
Avatar billede erikjacobsen Ekspert
24. januar 2009 - 19:29 #36
Der er ingen mærkelige tegn. æøå er æøå i utf-8 vist som iso-8859-1. Det skal du bare lade være med, hvis du ikke vil se de "mærkelige" tegn.
Avatar billede tmi Nybegynder
24. januar 2009 - 20:04 #37
Kan du ikke lige specificere idéen i UTF-8 lidt nærmere? Jeg lytter.. (IKKE).

Send lige et link til din side, så skal jeg fortælle dig om du bruger UTF-8 eller ej, hvilket alt tyder på du ikke gør!
Avatar billede akyhne Nybegynder
24. januar 2009 - 20:21 #38
Jeg kan kun sige at sider der kører med utf-8 kan bruge tegn som æ, ø, å, é o.s.v. DIREKTE, uden nogen form for konvertering. Hvorfor i alverden skulle man ellers bruge utf-8.
Jeg har sgu ikke forstand på det, derfor spørger jeg her. Men hvis du påstår jeg ikke kan bruge æ, ø og å direkte i min kode, ved jeg i hvertfald så meget at du ikke ved hvad du snakker om.
Avatar billede erikjacobsen Ekspert
24. januar 2009 - 20:40 #39
Det er fint nok at bruge utf-8. PHP er en smule bøvlet at bruge endnu - modsat nogle andre sprog, der har taget en anden tilgangsvinkel (Java, C# etc.)

Et eksempel:  http://n0p.com/861048.php  - php-filen gemt som utf-8:

<?
  header("Content-Type: text/html;charset=utf-8");
  $str="blåbærgrød";
  $len=mb_strlen($str,"utf-8");
  print "$str -> Length: $len<br>\n";
  for ($i=1;$i<=$len;$i++) {
    $s=mb_substr($str, 0, $i,"utf-8");
    print "$i: $s<br>\n";
  }
?>

Skulle gerne udskrive:

blåbærgrød -> Length: 10
1: b
2: bl
3: blå
4: blåb
5: blåbæ
6: blåbær
7: blåbærg
8: blåbærgr
9: blåbærgrø
10: blåbærgrød
Avatar billede tmi Nybegynder
24. januar 2009 - 21:01 #40
Hvorfor i alverden skulle man ellers bruge utf-8.
Det skal jeg fortælle dig, en byte består af 8 bit (0 eller 1), og det giver dig 256 mulige kombinationer: (00000000, 00000001, 00000010, 00000011, .. fortsæt selv). Men da fx kineserne har langt over 256 forskellige tegn bliver de nød til at bruge mere end 1 byte til at repræsentere dem. Og her kommer bl.a. UTF-8 så ind i billedet! Men da alle de tegn du og alle dine brugere benytter er formentlig er indeholdt i det vesteuropæiske tegnsæt (ISO-8859-1), hvor alle tegn kun fylder 1 byte, så giver det ikke mening for dig ikke at bruge det, især ikke når fx MySQL som standard også kører "latin-1", altså ISO-8859-1, har du husket at fortælle din database at det du smider i den er UTF-8?

Så hvis du siger din editor gemmer i UTF-8 og at din side bliver parset som UTF-8 af browserne, så vil et æ være et æ. Men hvis dit æ ikke er et æ begge steder, så kan de umuligt bruge samme tegnsæt. Derfor så skal du sætte din editor til at gemme i ISO-8859-1, hvis det er du bruger, eller Windows-1252, hvis det er det du ønsker.

At du sender header der angiver du bruger UTF-8 og meta tags der antyder det, betyder ikke at din browser respekterer det, fordi der er mange som dig der ikke forstår betydningen af forskellige tegnsæt, så de fleste browsere detekter selv hvilke tegnsæt du bruger. Prøv at sætte dette ind øverst i din PHP kode:

header("Content-Type: text/html; charset=UTF-8", true);

Og sæt dette ind i <head>-sektionen i din HTML kode:

<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></meta>

Og så åbn din side i FireFox, som jeg mener respekterer det, så vil du se at dine æ, ø og å'er vises korrekt, hvis de er UTF-8, mens de andre æ, ø og å'er der ikke er UTF-8 nu ikke kan vises.
Avatar billede akyhne Nybegynder
24. januar 2009 - 21:53 #41
For det første er det ikke en editor men en button generator jeg skal have bygget. Den skal understøtte så mange tegn som muligt. For det andet kører min side på en amerikansk host, hvor alt er sat op til at køre utf-8, incl. Mysql.
For det tredie kører Dreamweaver og Notepad ++ som jeg bruger, til at gemme i utf-8 (without bom).
Jeg er faktisk total ligeglad med hvordan teksten vises (det skal jeg ikke bruge), da den skal sammenlignes tegn for tegn med tegn i en utf-8 tabel. Derfor går jeg op i hvad format teksten har i en variabel, og ikke hvordan den vises i et printout.

erikjacobsen: Dit script virker på en dansk host, hvor jeg faktisk har opgivet at køre utf-8. På den originale host hvor jeg skal bruge scriptet, får jeg ikke vist teksten, da scriptet starter med <? og ikke med <?php. Er der nogen speciel årsag til at scriptet ikke skal starte med <?php?
Avatar billede erikjacobsen Ekspert
24. januar 2009 - 21:55 #42
Det bør starte med <?php
Avatar billede tmi Nybegynder
24. januar 2009 - 22:33 #43
Men hvorfor er det at du ikke gør som jeg skriver til dig? Jeg sagde ikke at du skulle skifte, jeg forklarede dig hvad du ikke selv forstod og forklarede dig løsningen på dit nye problem. Hvis du nu indsætter de to linjer i hhv. din PHP kode og din HTML kode så virker det jo, i stedet for at fortælle hvor smart din amerikanske host er og hvor smart dreamweaver er, we don't care.
Avatar billede akyhne Nybegynder
24. januar 2009 - 22:46 #44
Jeg skiftede fordi en af Jer forespurgte et link, og I kan ikke få det originale link.
Og ja, jeg kører med header("Content-Type: text/html; charset=UTF-8", true); og med
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></meta>.

Jeg fortæller dig ikke hvilke programmer jeg bruger for at være fancy, men for at fortælle dig at jeg har et program der gemmer i det rigtige format.
Avatar billede tmi Nybegynder
25. januar 2009 - 00:31 #45
Men siden du siger at dit æ bliver til flere end et tegn er der jo ingen tvivl om at din editor gemmer i UTF-8, i stedet er det din side der vises ikke vises i UTF-8. Var dit æ blevet til eet andet tegn, havde det formentlig været omvendt. Men hvis du ikke vil give os et link, er det lidt svært at forklare dig hvorfor det sker, da fejlen tydeligvis sker i brugerenden.
Avatar billede akyhne Nybegynder
25. januar 2009 - 12:57 #47
Oleboles måde at validere med w3 fejler jo netop med udskrivningen af teksten med din kode. Det er jo ikke browserafhængig fra min side.
Avatar billede tmi Nybegynder
25. januar 2009 - 13:10 #48
Jeg forstår ikke? Begge links indeholder UTF-8 og vises korrekt.. Hvad er det problemet er?

W3 validerer også siden korrekt: http://validator.w3.org/check?uri=http%3A%2F%2Fsmf.e-debatten.dk%2Fsmf_translated%2Ftest.php&charset=(detect+automatically)&doctype=Inline&ss=1&group=0&verbose=1&user-agent=W3C_Validator%2F1.606
Avatar billede akyhne Nybegynder
25. januar 2009 - 13:16 #49
Efter at have aktiveret print af arrayet med din funktion mb_str_split, fejler w3.
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 13:18 #50
Jeg har mistet tråden, akyhne - hvad er dine resterende spørgsmål?
Avatar billede akyhne Nybegynder
25. januar 2009 - 13:42 #51
Jeg kan ikke forstå hvorfor et æ både skulle kunne skrives i kildekoden som 'æ' og 'æ'. Ideen med utf-8 er at du kan bruge æøå direkte i din kode, at æøå gemmes som 'æøå' i databasen.

Hvis jeg skriver 'abcæøåæ' i kildekoden, kommer den ud som 'abcæøåæ'.
Hvis jeg skriver 'abcæøåæ' i en variabel, kommer den ud som 'abcæøåæ'

Altså er æ og æ ikke det samme. Det er det I siger det er.


I lang tid har jeg bøvlet med problemet med at få teksten indsat in en db som utf-8, og ikke med mærkelige tegn som æ for æ.
Jeg havde en lang diskution med erikjacobsen her: http://www.eksperten.dk/spm/845986
Det problem fik jeg løst i går. Der skulle simpelthen blot fortælles til MySql at vi var i utf-8 mode med koden

mysql_query('SET NAMES utf8');

..som skal komme lige efter MySql kaldet til MySql mysql_connect();
Nu får jeg vist mine danske æøå korrekt i databasen.

Så tekster indstat i MySql uden mysql_query('SET NAMES utf8'); bliver til sjove å'er, mens tekster med mysql_query('SET NAMES utf8'); aktiveret bilver indsat som de er.
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 13:49 #52
æ er to bytes, der i utf-8 repræsenterer bogstavet æ. Ser man de to bytes som iso-8859-1 vises de 2 tegn æ. Ser man de to bytes som utf-8 vises bogstavet æ.

Man kan ikke korrekt vise en følge af bytes korrekt på skærm eller papir, uden at fortælle hvilket tegnsæt, der anvendes
Avatar billede akyhne Nybegynder
25. januar 2009 - 13:55 #53
Erik: Hvis jeg går ind i phpmyadmin og kigger på tekst der er indsat uden SET NAMES, vises de som skøre å'er. På samme phpmyadmin side med tekst indsat med SET NAMES, vises de korrekt.
Avatar billede akyhne Nybegynder
25. januar 2009 - 14:15 #54
Hvis jeg laver et mysql udtræk uden mysql_query('SET NAMES utf8');, bliver teksten 'abcæøå' i databasen vist med 'abc firkant firkant firkant'.

Hvis jeg laver et udtræk med mysql_query('SET NAMES utf8');, bilver teksten vist med 'abcæøå'

I begge tilfælde vises æøå korrekt i kildekoden på den genererede php fil. Men visningen er forskellig!!!
Avatar billede tmi Nybegynder
25. januar 2009 - 14:36 #55
Lad mig lige forklar hvad et tegnsæt er igen, tænk på et tegnsæt som en lineær afbildning f : I^n -> T, hvor I er en mængde bytes og T er mængden af alle tegn, og så tænk på f^(-1) som den inverse funktion. Hvis du så trykker på tegnet C fra mængden T på dit tastatur, og din editor står til at køre UTF-8, så udregner din editor f_utf8^(-1)(C) = a, som er tilhører mængden I_utf8. Hvis du har sat den til iso88591 så udregner den funktionen f_iso88591^(-1)(C) = b, som tilhører mængden I_iso88591. Men da mængden I_iso88591 ikke nødvendigvis har noget tilfælles med mængden I_utf8, kan du ikke være sikker på at a = b. Så lad os sige at C = æ, så får du så b = {195,166} og b = 230. Så når du trykker gem i utf-8 så gemmer din editor tallene {195,166} på din harddisk, og har du iso-8859-1 så gemmer den tallet 230. Hvis du så åbner filen du gemte i utf-8 og fortæller din editor at det er iso-8859-1, så tager den f_iso88591(195) = Ã og derefter f_iso88591(166) = ¦. Den tager altså tallene hvert for sig fordi det er sådan f_iso88591 er defineret. Tager du åbner den du gemte i ISO-8859-1 med en UTF-8 editor så laver den operationen f_utf8(230), så får du en fejl, fordi 230 ikke er indeholdt af mængden I_utf8, f_utf8 er altså simpelthen ikke defineret i det punkt. Åbner du så iso-filen i iso-8859-1 laver den f_iso88591(230) = æ. Åbner du utf-8 i utf-8 vil den muligvis prøve først at lave f_utf8(195), men dette vil også give en fejl da dette tegn ikke eksisterer. Men da det jo kan være en multibyte tager den så og kombinerer denne byte med den næste: f_utf8({195,166}) = æ. Men hvis du laver rod i tegnsættene kan du få brug for enten funktionen utf8_decode : I_utf8 -> I_iso88591, eller den inverse utf8_encode : I_iso88591 -> I_utf8, som konverterer bytesne.

Så kan du nu forstå at hvis du gemmer et utf-8 æ i den editor så bliver det til {195,166}, og når du så putter det ud på din hjemmeside downloader vi også tallene {195,166}, så hvis vores værktøjer åbner det i utf-8 for vi et æ, ellers gør vi sikkert ikke og det samme gælder dine værktøjer.

Men hvis du så tager et utf-8 æ og gemmer det i din database, så er det fuldstændig ligegyldigt om din database er indstillet til utf-8 eller latin-1 da det den gemmer er de 2 byteværdier. Den eneste forskel er at hvis du har oprettet et felt med længden 1, så kan du kun putte et halvt utf-8 æ i den, hvis den er sat til latin1, men hvis den er sat til utf-8 så finder den selv ud af at det er en multibyte og udvider dit felt til 2 bytes uden at fortælle dig det. Når du så trækker ud fra din database igen får du præcis de samme tegn som du puttede i den uanset hvilket tegnsæt den står til.

Men hvis du selv putter data i din database vha. fx phpMyAdmin, som virker ordentligt, så sørger den for at putte rigtig data i din tabel. Men da MySQL's interface som standard er i latin-1 og du putter utf-8 i den uden at fortælle det er utf-8 så gemmer du noget andet end du havde tænkt dig, så bliver dit utf-8 data fra PHP blandet med de ting som phpMyAdmin har lagt i i latin1. Men når du så skriver mysql_query("SET NAMES utf8;");, så sørger mysql selv for at konvertere dit utf-8 data til latin-1 med den lineære afbildning utf8_to_latin1 : I_utf8 -> latin1, og når du så trækker data ud igen sørger den for igen at konvertere dit data tilbage med funktionen latin1_to_utf8 : I_latin1 -> I_utf8 , så nu er både det PHP lægger i din database og det du selv lægger i din database gemt som elementer i I_latin1.

Hvis du nu igen stiller et dumt spørgsmål er du simpelthen så dum at jeg giver op.
Avatar billede locke Nybegynder
25. januar 2009 - 16:24 #56
tmi, er du faret vild?
Avatar billede tmi Nybegynder
25. januar 2009 - 16:33 #57
Nej, jeg er bare træt af at han ikke forstår hvad det er han får at vide :-p. Håber han får en lidt bedre forståelse for hvad der egentligt sker nu, og så selv kan regne ud hvad det er han gør forkert.
Avatar billede snowball Novice
25. januar 2009 - 16:46 #58
tmi: Det er muligt, at du er frustreret over, at andre ikke er så godt inde i emnet som dig selv, men hold venligst dine frustrationer for dig selv så dine indlæg overholder reglerne om sober tone - http://www.eksperten.dk/regler.phtml punkt 2.2

Tak.

Snowball / Admin
Avatar billede tmi Nybegynder
25. januar 2009 - 17:57 #59
Men han har jo fået svar på sine spørgsmål, så er det da irriterende at jeg bliver ved med at få emails hvor han spørger om det samme hele tiden, der i øvrigt intet har med det originale spørgsmål at gøre (og dette siger jeg med reference til reglen 2.1.8)? Han har selv postet et link hvor han viser at de løsninger jeg har givet ham i kommentar 1 og 11 virker.

Og, hvis han har ret til at bilde folk ind at hans opfattelse af UTF-8 er den korrekte, når den er fuldstændig forkert, så har jeg da også ret til at argumentere for at han er et fjols?
Avatar billede snowball Novice
25. januar 2009 - 19:53 #60
tmi: Nej! Du har ingen ret til at kalde folk navne - lige meget hvor frustreret du er.

Jeg har læst hele spørgsmålet igennem, men jeg har ikke indsigt nok i dette emne til at kunne afgøre om din løsning er korrekt eller ej, men så længe "akyhne" ikke kan få det til at virke, så er hans problem jo ikke løst.

Mht. punkt 2.1.8 i reglerne, så kan jeg ikke se hvad det skulle have med sagen at gøre. Så længe "akyhne" ikke mener hans problem er løst, så er han da i sin fulde ret til at blive ved med at skrive i spørgsmålet.

Jeg vil desuden minde folk om, at hvis de ikke har tålmodighed eller temperament til fortsat at deltage i et spørgsmål, så står det jer altid frit for at melde jer ud af spørgsmålet - emails kan afmeldes ved at fjerne krydset i "Abonnér" til venstre for indtastningsfeltet.

Snowball / Admin
Avatar billede akyhne Nybegynder
25. januar 2009 - 20:21 #61
Jeg sidder lige og studerer nettet for artikler om emnet, og jeg har ikke fundet noget der modsiger hvad jeg mener - at tekst gemt i en utf-8 database netop bliver vist som teksten oprindeligt er skrevet - ingen specialtegn her. At hver tegn så dybest set fylder mere end 1 byte er en anden sag.
Hovedsagen er at de mærkelige å'er gemt i databasen også bliver udskrevet som mærkelige å'er når alt er sat rigtig op.

Jeg har et punkt som jeg ikke kan forstå i forhold til hvad tmi siger, og som efter min mening understøtter min forståelse:
Jeg har en mysql db med 2 varchar felter men en maks. på 60 karakterer i hver.
I den ene skriver jeg så mange 'a' det er muligt, i den anden så mange 'å' som det er muligt. Derefter gemmer jeg.
Resultatet: Der er 60 a'er og 60 å'er. Altså kan det ikke passe at hver specialtegn skal fylde 2 tegn i databasen. Jo, de fylder jo nok 2 bytes plads i databasen, men ikke 2 tegns plads.
Og ja, tmi, jeg kender "alt" til bits & bytes, så en nedgørelse er ikke nødvendig.

En af de ting jeg har læst mig til er at hvis specialtegn bliver gemt så de vises som mærkelige tegn i databasen, er utf-8 ikke sat korrekt op, og dermed giver det store problemer med f.eks et søgesystem i et forum eller lignende.
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 21:18 #62
Der er ingen specialtegn, eller mærkelige tegn, som jeg tidligere har skrevet. Jeg skrev også:

"æ er to bytes, der i utf-8 repræsenterer bogstavet æ. Ser man de to bytes som iso-8859-1 vises de 2 tegn æ. Ser man de to bytes som utf-8 vises bogstavet æ.

Man kan ikke korrekt vise en følge af bytes korrekt på skærm eller papir, uden at fortælle hvilket tegnsæt, der anvendes"

Så hvis det "ikke virker", så er det fordi følgen af bytes ikke vises med det rigtige tegnsæt.

Og hvis det "virker", så er det ikke bare fordi, det virker, men fordi indhold og visning passer sammen.

På samme måde kan man ikke skrive, som du gør: "Det vil sige at æ gemmes som æ etc." Der findes ikke noget, man kan kalde et "æ", der findes repræsentationer af "æ", der fylder eet eller flere bytes, og denne repræsentation gemmes.

Men har du noget konkret kode vi skal kigge på, eller skrive?
Avatar billede akyhne Nybegynder
25. januar 2009 - 21:50 #63
Erik, det jeg mener er at hvis jeg gemmer noget til Mysql fra en php fil hvor både mysql databasen kører i utf-8, tabellen, kolonnerne kører i utf-8, samt php scriptet kører i utf-8, skal teksten i phpmyadmin vises som æøå hvis jeg indsætter æøå.
Men tmi skriver at hvis jeg indsætter æøå uden brug af mysql_query('SET NAMES utf8');, skal resultatet være æøå som så skulle være æøå. Men hvis jeg bruger mysql_query('SET NAMES utf8');, skal teksten vises som æøå.

Laver jeg så disse to forsøg, vil jeg have en række i min tabel der har værdien æøå og en der har værdien æøå. Det skulle efter tmi's mening så være det samme!!! Det kan da aldrig blive det samme!

Jeg har nu efter intens læsning fundet ud af at man altid skal bruge mysql_query('SET NAMES utf8'); for at overføre utf-8 til en db som utf-8, og for at trække ud af samme. Det gør så også at jeg ser teksten som jeg ønsker, nemlig æøå=æøå.
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 21:54 #64
Du kan selvfølgelig gemme æøå som utf-8 - det er muligt, men næppe hvad du ønsker i dette tilfælde.

Så du har fundet en løsning - eller løsningen... ;)
Avatar billede akyhne Nybegynder
25. januar 2009 - 22:07 #65
Det ser nu ud til at alt virker:

header("Content-Type: text/html; charset=utf-8");
Ser ikke umiddelbart ud til at have effekt, da siden i sig selv har en header og et meta tag der fortæller at jeg bruger utf-8. Men linien vil nok være nødvendig, hvis der ikke er en html header.

print mb_internal_encoding();
Da den er sat til iso i min php.ini, får jeg også ISO-8859-1 på print mb_internal_encoding();

mb_internal_encoding("UTF-8");
Nu skriver print mb_internal_encoding(); endelig UTF-8. Nu virker tmi's kode også korrekt, og fejler ikke i w3's validator. Alt tekst bliver både i kildekoden og på udskriften vist korrekt. D.v.s æøå vises som æøå

function mb_str_split(); //pænt givet af tmi.
Den virkede blot ikke uden mb_internal_encoding("UTF-8");, men virker nu som den skal. Med angivelsen af mb_internal_encoding, er det nu ikke engang nødvendig med utf-8 angivelsen i mb_strlen();. Det er jo nok fordi alt nu kører korrekt i utf-8. Æ, ø og å vises som de skal i databasen, nemlig som korrekt æ, ø og å.

Konklusion: Efter at have fået angivet de rette parametre, ser det nu ud til at alt virker. Det viste sig at være en sammenblanding af flere gode råd, samt en masse læsning på nettet.
Avatar billede akyhne Nybegynder
25. januar 2009 - 22:11 #66
Erik: Hvis et æ gemmes som æ i en utf-8 database, må det jo nødvendigt bruge op til 4 bytes, såfremt både à og ¦ fylder 2 bytes hver. Det skal jeg ikke gøre mig klog på om de gør. Det er blot ikke meningen med brug af utf-8. Selv et @ skulle blive vist som @, såfremt man har Mysql til at køre i korrekt utf-8 mode.
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 22:17 #67
Du udskrev på baggrund af oleboles forslag mb_internal_encoding(), og hvis den ikke siger utf-8, så skal du skrive det i funktionerne, eller sætte det i starten af dit script med http://php.net/mb_internal_encoding.

Jeg kan ikke lige gennemskue hvorfor du fik udskrevet ISO-8859-1 - det er vel en opsætningsfejl...?

Char-set i meta-tag er aldrig nok, men nødvendigt. Browseren skal altid tage det tegnsæt, der angivet i http-headeren med http://php.net/header , eller pr. webserver-indstilling, men man bør også skrive det i meta-tag, hvis brugeren gemmer siden på sin HD. Altså: altid begge steder.
Avatar billede akyhne Nybegynder
25. januar 2009 - 22:17 #68
Nå ja, så glemte jeg lige at enhver mysql_connect(); skal afsluttes med mysql_query('SET NAMES utf8'); for at være sikker på at data til/fra Mysql udføres i utf-8.

Så ja, det er mere besværligt at køre i utf-8 mode. Jeg havde ikke regnet med det var så besværligt. Et tegnsæt er vel et tegnsæt... men nej.
Avatar billede tmi Nybegynder
25. januar 2009 - 22:22 #69
Nej.. (Jeg har altså afmeldt, jeg ved ikke hvorfor jeg bliver ved med at få emails?!), men, det jeg siger er, hvis du laver en tabel uanset hvilket tegnsæt du sætter den til at være. Så oversætter MySQL for dine kommandoer så det passer. Dvs.:
CREATE TABLE test (
myfield VARCHAR(20) NOT NULL
) CHARSET=latin1 COLLATE latin1_swedish_ci;

Hvis du så bruger phpMyAdmin og lægger data i den med Æ, Ø og Å, så bliver det lagt i som latin1, det sørger phpMyAdmin nemlig for.

Hvis du bruger PHP og du gemmer det her i UTF8 og kører det:
mysql_query("INSERT INTO test (myfield) VALUES('æblegrød')");

Så er MySQL indrettet sådan at den ikke konverterer det fordi den går ud fra at du giver den latin1. Nu har du så 2 muligheder for at vise de 2 rækker der ligger i tabellen, hvis du tager phpMyAdmin, så vil den første stadig blive vist rigtigt, mens den du lige har lavet vil blive vist forkert. Men hvis du trækker begge rækker ud med php:
header("Content-Type: text/plain; charset=UTF-8");
$q = mysql_query("SELECT * FROM test");
while ($d = mysql_fetch_assoc($q)) echo $d['myfield']."\n";

Så vil den først blive vist forkert, men æblegrød vil blive vist korrekt. Hvis du så bagefter gør det her i PHP:
header("Content-Type: text/plain; charset=UTF-8");
mysql_query("SET NAMES utf8");
$q = mysql_query("SELECT * FROM test");
while ($d = mysql_fetch_assoc($q)) echo $d['myfield']."\n";

Så vil æblegrød blive vist forkert, men den første blive vist korrekt, altså vil du se det samme som du så i phpMyAdmin, fordi MySQL så konverterer dit data fra latin1 til utf8 for dig. Og din utf8 æblegrød vil altså også blive konverteret som var det latin1, og det giver dig noget sandsynligvis volapyk.

Tager du det samme eksempel igen, men hvor du laver tabellen:
CREATE TABLE test (
myfield VARCHAR(20) NOT NULL
) CHARSET=utf8 COLLATE utf8_swedish_ci;
Og du ikke angiver SET NAMES, som i eksemplet, så vil den konvertere dit data fra latin1 til utf-8 uanset om det var utf8 i forvejen eller ej, og dit problem vil være fuldstændig analogt med eksemplet.

Vær opmærksom på at hvis din tabel var latin1 før, og du har været inde og rette så den nu er utf8 efter du har puttet data i, så har MySQL også automatisk konverteret det data der var i fra latin1 til utf8, så det løser ikke dit problem, du bliver nød til manuelt at indtaste alt igen eller få et program til at decode alle rækker efter du har skiftet tegnsæt. Hvis du så herefter altid sørger for at bruge SET NAMES utf8 vil det virke efter hensigten både i phpMyAdmin og på din hjemmeside.
Avatar billede akyhne Nybegynder
25. januar 2009 - 22:36 #70
"Jeg kan ikke lige gennemskue hvorfor du fik udskrevet ISO-8859-1 - det er vel en opsætningsfejl...?"
Sådan er mit egen php.ini sat op på serveren:
mbstring.internal_encoding ISO-8859-1

"Char-set i meta-tag er aldrig nok, men nødvendigt. Browseren skal altid tage det tegnsæt, der angivet i http-headeren med http://php.net/header , eller pr. webserver-indstilling, men man bør også skrive det i meta-tag, hvis brugeren gemmer siden på sin HD. Altså: altid begge steder."
Indrømmet, jeg har en lidt mærkelig måde at kode php på. Jeg koder en del i ren html og resten i php. Jeg troede dog faktisk ikke man kunne bruge header() hvis det for eks. er en side der blot skal generere et billede som i mit tilfælde! Der vil jeg jo også skulle bruge header('Content-type: image/png'); til at udskrive filen. Det må komme an på en prøve.
Avatar billede akyhne Nybegynder
25. januar 2009 - 22:37 #71
tmi: Dette projekt har fra dag 1 kørt i utf-8 i MySql.
MySql siger:
MySQL Tegnsæt:  UTF-8 Unicode (utf8)
MySQL forbindelses-sammenkøring::  UTF-8 Unicode (utf8) utf8_unicode_ci (det er måske her sammenkørslen til php går galt uden brug af SET NAMES)
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 22:43 #72
Ja, du skal sætte en passende content-type på scripts, der genererer billeder. Hvis du ikke gør det, så prøv et par forskellige browsere ;)
Avatar billede tmi Nybegynder
25. januar 2009 - 22:44 #73
Ja så får det problem jeg nævnte når du pludselig skifter NAMES, for det vil sige at alt det data du har lagt i via phpMyAdmin er blevet gemt som UTF-8, mens alt det data du har lagt i vha. PHP før du begyndte at bruge SET NAMES er blevet konverteret fra latin1 til utf8, selvom det i forvejen utf-8, og nu har du så en blanding. Du bliver derfor nød til at tage alt det data du i forvejen har puttet i og så decode det fx med en funktion:
$q = mysql_query("SELECT * FROM utf8tabel WHERE data is from PHP");
while ($d = mysql_fetch_assoc($q)) foreach ($d as $k => $v) mysql_query("UPDATE utf8tabel SET `$k` = '".addslashes(utf8_decode($v))."' WHERE id = '".$d['id']."'");
Avatar billede akyhne Nybegynder
25. januar 2009 - 23:09 #74
Jeg har egentlig ikke behov for at indsætte data i tabellen, blot at køre en sammenligning mellem db og php scriptet. Delen med at indsætte teksten var blot for at konstatere hvorfor koden ikke ville finde specialtegn.

I har alle gjort Jer fortjent til point, undtagen snowball & locke ;)

Smid et svar hvis I ønsker point.
Avatar billede erikjacobsen Ekspert
25. januar 2009 - 23:25 #75
Nej tak.
Avatar billede htx98i17 Professor
26. januar 2009 - 21:01 #76
må jeg lige stille et opklarende spm til tmi. Giver gerne point for det. Det er nemlig lidt forvirrende hvad man så skal gøre.

Hvis jeg har en database:
MySQL Tegnsæt: UTF-8 Unicode (utf8)
MySQL forbindelses-sammenkøring::  UTF-8 Unicode (utf8) utf8_unicode_ci

Og sørger for
header("Content-Type: text/plain; charset=UTF-8");

i dokumentet, samt gemmer i utf8 format.

Er det så hvad der skal gøres for at lave det korrekt? eller er SET NAMES nødvendig?
Avatar billede tmi Nybegynder
26. januar 2009 - 21:20 #77
Ja, det må du, skal nok prøve at tale pænt ;-)

Når du siger MySQL forbindelses-sammenkøring, så forstår jeg det som SET NAMES?
I MySQL er der tegnsæt i 4 niveauer:
1: Default tegnsæt for databasen. Dette betyder at hvis du opretter en tabel i databasen, vil den som default give dette tegnsæt til alle felter.
2: Default tegnsæt for tabel, dette betyder at hvis du opretter et felt i tabellen så vil feltet kører efter dette tegnsæt (overruler altså database default)
3: Tegnsæt for felt, du kan specificere tegnsæt for hvert felt i din tabel (mener dog ikke man kan have utf8 i et felt og så latin1 i et andet felt i samme tabel, men du kan vidst nok have forskellig collation).
4: MySQL klienten.

Alle 4 niveauer kører som default latin1. Så hvis du opretter en tabel hvor alle felter er utf8, betyder det ikke at du forbindelsen til serveren er sat til utf8 også.

Så hvis din side kører i utf8 bliver du altså nød til at bruge SET NAMES utf8, da MySQL ellers vil konvertere al dit data fra latin1 til utf8, fordi den går ud fra at du giver den latin1. Giver du den så utf8 alligevel uden at fortælle den det så afbilder den dit utf8 data i funktionen latin1_to_utf8, hvilket vil gå meget galt for specialtegn. Giver du den SET NAMES utf8 vil den afbilde dit data med funktionen utf8_to_utf8, hvilket selvfølgelig ikke ændrer det, og dit data vil blive gemt korrekt. Jeg ved ikke hvorfor de har valgt automatisk at konvertere folks data, det er meget irriterende =). Men summa summarum, så konverterer den dit data fra, det NAMES står til, til det de enkelte felt står til. Og NAMES står altså til latin1 hvis du ikke ændrer det.
Avatar billede tmi Nybegynder
26. januar 2009 - 21:42 #78
Og det skal måske lige tilføjes at NAMES altid vil stå til latin1, når du opretter forbindelse, så det skal du sætte hver gang du opretter forbindelse. Dog kan det formentlig ændres i my.ini (MySQL's konfigurationsfil), hvis du har adgang til den.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester