Webboken

Teckenkodning

Unicode skulle skapa världsfred; istället fick vi kaos

I kapitel 2 gick vi snabbt igenom hur vilken teckenkodning som används på aktuell webbsida deklareras när dokument lagras lokalt. Vi ska i detta kapitel ta en mer grundlig koll på vad en teckenkodning egentligen innebär och varför vi nästan alltid vill välja en av Unicode-typ, men även en snabb blick på vad som måste du måste ha i åtanke när webbläsaren hämtar en webbsida från en webbserver istället för lokalt på din egen dator.

Kort historik

I början av datorns historia används endast ett par tecken, till en början bara siffror. När man sedan kom på att flera tecken behövdes så lades alla tecken från a till z, skiljetecken, mellanrum och andra tecken man kände ett behov av till i samlingen. När datorn sedan blev mer och mer populär började program översättas till ”nya” språk och nya nationella tecken infördes, som till exempel svenskans ”å”, ”ä” och ”ö”. Allt eftersom informationsutbyte mellan datorer ökade i popularitet, inte minst genom Internets, behövdes nya standarder över hur dessa tecken skulle sparas för att alla datorer skulle kunna visa samma fil på samma sätt. Om det inte skulle skapats regler för hur tecken sparades skulle två filer med exakt samma innehåll kunna bete sig på olika sätt på olika datorer. Därför skapades standarder så som American Standard Code for Information Interchange (ASCII). Nu kunde man byta information med varandra, och den behöll sitt ursprungliga utseende. På grund av lagringstekniken som användes, som vi kommer till senare, fick inte alla tecken från världens alla olika språk ”plats” i ASCII. Därför behövdes flera olika standarder för att täcka alla olika språk som finns. Detta ledde såklart till en horribel röra av teckenkodningar. Därför infördes Unicode som är tänkt att i princip ersätta alla tidigare standarder, så vi bara behöver använda oss av en standard för alla språk.

Behovet av stora teckenuppsättningar

När vi använder Unicode behöver vi nästan aldrig använda teckenreferenser (förutom de som är definierade i XML av naturliga anledningar). Detta leder naturligtvis till renare och genom det mer lättläst kod. Så teckenreferenser ska endast användas när du verkligen inte har något annat val.

Men vart kommer då citattecken in i bilden? Jo, förr i tiden när man använde skrivmaskiner så hade vi bara " och ' att välja på när vi skulle skriva citat. (Och `, men det går vi inte in mera på nu.) Detta ledde så klart till att man använde dessa. Men nu vet ju alla att ”riktiga citationstecken” inte ser ut så. Dessa är de ”riktiga citationstecken”: ’ och ”. Nej, det är varken primtecknet (′) eller dubbelprimtecknet (″) (som har helt andra användningsområden), det är våra svenska citattecken! Du har troligen läst någon engelsk text och sett att de använder “- och ”-tecknen för att påbörja respektive avslutat citat, men här i Sverige använder vi ”-tecknet för att påbörja och avsluta ett citat.

Nu är det så att ISO-8859-1 och andra gamla teckenkodningar inte innehåller de ”riktiga citationstecken”; men det gör Unicode förstås. Så om vi använder oss av Unicode är det bara att skriva in dessa tecken som vilket annat tecken som helst. Men om vi istället använder någon annan (gammal) standard får du träna dina teckenreferenskunskaper varje gång du ska göra ett citat. (Då kan du ju räkna ut hur lättläst den koden blir sedan.)

För dig som undrar hur vi kom in på detta kan vi svara dig med att det bara är en litet stycke som visar att alla har nytta av Unicode, även om de inte ska blanda in kinesiska och tyska tecken på sin webbplats. Och för att fler personer ska använda korrekta citattecken, förstås!

Mer om Unicode

Som du säkerligen tidigare hört sparar en dator all sin information i ettor och nollor, det så kallade binära talsystemet med basen två alltså. Det finns en rad olika tekniker att lagra och tolka tecken. Av alla dessa tekniker är en Unicode-variant att rekommendera idag av tidigare nämnda anledningar. Vi kommer i detta kapitel ta upp dess betydelse och hur du kommer att kunna använda det på din webbplats.

Fördelen med Unicode är som sagt att det har plats för massor av tecken, närmare bestämt alla nu levande språk (och några utdöda). Du kan därför använda alla dessa på samma webbisda. Detta leder till att du till exempel kan skriva kinesiska tecken på en svenskspråkig sida om du vid något udda tillfälle skulle känna behov av det. (Vi kommer ta mer troliga exempel senare.) Du behöver heller aldrig tänka på vilken teckenuppsättning du bör använda dig av, vilket är kanske den största fördelen.

Rensa här under.

Gemensamt för alla teckenkodningar är att varje tecken representeras av ett tal. Låt oss säga att vi skapar vår eget mycket simpla teckenkodning som endast ska ha plats för ”A”, ”B”, ”C”. Vi låter ”A” representeras av 1, ”B” av 2 och ”C” av 3. För att datorn ska kunna spara dessa måste de konverteras till det binära talsystemet, det vill säga ettor och nollor. Utan att gå in djupare på hur man konverterar dessa tal från vårt decimala talsystem (med basen 10) till det binära talsystemet (med basen 2) kan vi bara finna oss i att 1 = 01, 2 = 10 och att 3 = 11. Vi ser att våra tecken får plats på två ettor och nollor, eller som man brukar kalla de, bitar (eng. bits). Men vad händer om vi sedan vill utöka vårt nuvarande talsystem som är begränsat till två bitar med till exempel ”D”, ”E” och ”F”? De får helt enkelt inte plats! Om vi fortsätter vår redan påbörjade räkning så blir ”D” = 4, ”E” = 5 och ”F” = 6. I det binära talsystemet skulle det decimala talet 4:a bli 101. Vi inser att vi inte kan lagra dessa tre bitar i två bitar. Vi behöver helt enkelt använda tre bitar till varje tecken. Nu blir ”A” = 001, ”B” = 010, ”C” = 011, ”D” = 100, ”E” = 101, ”F” = 110. Om vi skulle använt vår första teckenkodning som var begränsad till två bitar per tecken skulle strängen ”ABC” endast ta 6 bitar (01 + 10 + 11 = 6 bitar), men med vår utökade teckenkodning tar det istället 9 bitar (001 + 010 + 011 = 9 bitar). Eftersom de första tecknen som egentligen fick plats på två bitar nu lagras på tre bitar kommer det finnas en bit som aldrig används i tecknen som representeras av låga värden, ”dött utrymme” alltså.

Om nu det så kallade UTF-8 skulle rymma hela världens alla tecken, skulle det inte betyda att vi får massor av ”dött utrymme” då? Alla tecken skulle ju behöva massor av bitar för att man skulle få plats med tecknen som representeras av mycket höga tal, eller? Som tur är använder UTF-8 något man kallar variabel teckenlängd, vilket betyder att alla tecken allokerar inte ett lika stort antal bitar. När man pratar om till exempel ISO-8859-1 (även kallat Latin 1), som inte är en Unicode-variant, så svarar en byt mot ett tecken. (En byte är åtta bitar, det vill säga åtta ettor och nollor.) Detta betyder alltså att alla tecken är lika stora, precis som i vårt talsystem från stycket ovan. I ISO-8859-1 har ”a” det binära värdet 01100001 (97 decimalt), och tecknet ”ä” representeras av 10000100 (132 decimalt). Om vi räknar dessa bitar får vi fram att båda tecknen representeras av åtta stycken ettor och nollor, precis som vi tidigare sade (vi har alltså rätt ibland). Detta slutar precis som med vårt eget talsystem, vi får plats med ett begränsat antal tecken. Etta eftersom varje tecken måste ha ett eget unikt värde, hur skulle datorn annars veta om du menade ”m” eller ”n”, om båda hade samma binära värde? Det enda sättet att ”få plats med fler tecken” är som vi redan sett att tilldela varje tecken ett större antal bitar. Det är här UTF-8 kommer in i bilden: genom att olika tecken representeras av olika många bitar räddar den oss från alla dessa problem. Den tidigare nämnda ”variabla teckenlängden” är nyckeln här. Då tar vi inte upp massor onödigt utrymme och vi får tillgång till nästan hela världens tecken! De vanligaste tecken, a till z till exempel, använder sig av lika många bitar som de äldre standarderna, så där ”förlorar” vi inget utrymme.

Det finns andra viktiga Unicode-teckenkodningar, bland annat UTF-16 och UTF-32. De använder sig dock inte av variabel teckenlängd i samma utsträckning, och lämpar sig därför inte för webben eftersom de tar mer (onödig) plats. Så sammanfattat, UTF-8 bör användas i så stor utsträckning som möjligt.

Att använda Unicode på webbplatser

Nu när vi gått igenom den tekniska delen av teckenkodning är det bara det lätta kvar: hur man talar om för besökarens webbläsare vilken teckenkodning som används. Om vi inte skulle göra det skulle standardteckenkodningen användas, vilket varierar beroende på vilken webbläsare hon eller han använder och språkinställningar i denna. Inget du vill förlita dig på alltså. Detta leder väldigt ofta till att fel teckenkodning används om webbutvecklaren (ja, det är du!) inte gjort så att webbläsaren kan ta reda på viken teckenkodning som används.

Det bästa sättet att tala om för besökaren vilken teckenuppsättning man har använt är att sätta ett så kallad HTTP-huvud vid namn Content-Type. För att förstå vad detta egentligen betyder behöver man förstå hur datorer i ett nätverk, så som Internet, kommunicerar med varandra och hur HTTP-protokollet är uppbyggt. Detta är något någon annan får skriva en bok om, vi kommer bara gå igenom det vi behöver veta för att få det fungera.

HTTP, protokollet för kommunikation mellan dig och webbservern

När du besöker en webbplats så hämtar webbläsaren information från en webbserver. För att de ska förstå varandra har W3C och IETF utvecklat ett protokoll vid namn HTTP. Ett protokoll är en sammansättning regler och bestämmelser som både webbläsaren och webbservern måste följa för att de ska ha en chans att förstå varandra, man kan säga att de ”prata med varandra”. Det går i stora drag till på följande vis:

  1. Webbläsaren skickar en GET-begäran till webbservern innehållande filnamnet på filen besökaren vill se.
  2. Webbservern kollar om filen finns på sin disk och kan sedan svara med en rad olika felkoder om något gick fel. Du har säkert hört talas om 404, den felkod som skickas när webbservern inte kan hitta filen som efterfrågas.
  3. Om allt gick rätt så kommer webbservern att svara med koden 200 och sedan skicka webbsidan till besökaren.

HTTP-svarskoden ser besökaren inte så länge inget gick fel och HTTP-huvudet är information till webbläsaren och inte besökaren. Ett HTTP-svar kan se ut såhär:

HTTP/1.1 200 OK

Date: Mon, 24 May 2006 22:37:32 GMT
Server: Apache/1.3.27 (Unix)
Last-Modified: Wed, 09 Jan 2004 13:15:05 GMT
Content-Length: 438
Connection: close
Content-Type: text/html; charset=UTF-8

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
<title>Kolla, jag använder UTF-8!</title>
</head>
<body>
<p>Denna rad är då förhoppningsvis kodad som UTF-8. T.ex. fungerar öäå perfekt.</p>

</body>
</html>

Här är det bara det sista, Content-Type (den markerade raden), som du behöver bry dig om just nu av alla dessa HTTP-huvuden. Vi ser i exemplet att den har värdet text/html; charset=UTF-8. Det första är MIME-typen (text/html i exemplet) som vi pratade om i förra kapitlet. Efter det har vi delen som är aktuell i nuvarande kapitel, nämligen charset=UTF-8. Det betyder att denna sida är kodad i UTF-8. Vi kommer ta upp två sätt att ändra värdet av Content-Type (vi bakar alltså in delen om hur man sätter den så kallade MIME-typen).

Ändra Content-Type direkt i webbservern

Även om du inte har eller använder en webbserver just nu så kan det vara bra att läsa igenom detta för att förbereda sig på vad som måste göras senare när du ska publicera din sida. En förklaring om du hanterar filer utan en webbserver kommer senare.

Det är inte ofta man har tillgång till att ändra inställningarna direkt på webbservern, om man inte känner eller själv är ägaren av servern. Hur man går till väga för att ändra inställningar på webbservern beror tyvärr på vilken webbserver man använder. Den mest använda webbservern idag heter Apache, och finns till nästan alla operativsystem. Den är dessutom gratis för alla ändamål. Eftersom tillvägagångssättet skiljer sig från server till server får du helt enkelt börja med att söka igenom din webbservers manual, som ofta finns tillgänglig på respektive utvecklares webbplats, och hoppas på att det finns information på hur du bör göra där.

Om du hyr ett webbhotell och inte vet vilken typ av webbserver de använder använder får du kontakta supporten. Alternativt om du vet om något smidigt sätt att kontrollera vilka HTTP-huvud som webbservern skickar till din webbläsare då programnamnet ofta står där. Det brukar inte heller vara så att webbhotellen försöker dölja vilken webbserver de använder, de brukar snarare skylta med det, typ ”eftersom vi är bäst och Apache är den bästa webbservern tyckte vi det var en bra kombination och använder därför den”. Se i vilket fall till att de berättar hur man går till väga för att ändra inställningar, så kan du göra det själv nästa gång. Om ditt webbhotell inte tillåter dig ändra inställningarna på något sätt, det är sällan man får det på gratis webbhotell, får du använda dig av samma teknik som filer lagrade lokalt.

Vi tänkte visa hur man gör ovanstående med en Apache-server då chansen är stor att du använder en sådan. (Apache har som många andra sin dokumentation tillgänglig online.) Om du inte har tillgång till att ändra direkt i servern så är chansen stor att du får ändra dessa inställningar individuellt per mapp. Detta gör du genom att skapa en fil med namnet .htaccess i mappen. Notera att även mappens undermappar kommer påverkas av dessa inställningar.

Man kan självklart kombinera dessa, så att man kan använda både HTML och XHTML på sin server:

AddDefaultCharset utf-8
AddType application/xhtml+xml;charset=utf-8 .xhtml

Lägg märke till att du inte kan ha något mellanrum mellan ; och charset-parametern. Skulle du skriva AddType application/xhtml+xml; charset=utf-8 .xhtml skulle Apache endast skicka application/xhtml+xml;, det vill säga charset-parametern faller bort.

Som du säkerligen märkte gick vi lite snabbt och lustigt igenom hur man ändrar MIME-typ på XHTML-filer också. application/xhtml+xml är oftast den förinställa MIME-typen på .xhtml-filer, men för att vara på den säkra sidan är det lika bra att ta med det. Vissa personer påstår prompt att charset ska utelämnas ur Content-Type när man skickar XML (XHTML är XML som du säkert kommer ihåg), eftersom det är ett ”självbeskrivande format”. Man ska enligt dessa personer endast ange encoding-värdet i XML-deklarationen, som vi tar till efter denna del. Men det är värt att redan nu känna till så att det inte blir allt för rörigt.

Filnamnet .htaccess brukar skapa problem på vissa operativsystem, speciellt Windows. Windows påstå att ”Du måste ange ett filnamn” när du försöker skapa filen. Men om du istället man skapar filen genom att helt enkelt spara den på vanligt sätt (och genom det skapa den) med din textredigerare så brukar detta inte vara ett problem. Sedan fungerar den som vilken fil som helst. Windows är lustigt ibland.

Ändra Content-Type med ett så kallat serverskript

Vi vill börja med att utdela en liten varning först: denna lösning är mycket krångligare än ovanstående och är endast en nödlösning om allt annat misslyckats.

Ett serverskript är ett skript som körs innan webbsidan skickas till webbläsaren och något som du måste kontrollera att din webbserver har stöd för innan du kan använda det. Det finns flera olika sådana språk, och PHP är ett av de mest populära idag. Som tur är det dessutom relativt lätt att göra det vi vill i PHP. För att säga till webbservern att det är PHP-kod vi skriver just nu så skriver man <?php som starttag avslutar kodbiten med sluttaggen ?>. Dessutom använder man ändelsen .php på filen i fråga. Det är viktigt att skriptet vi kommer använda oss av står först i HTML-koden, annars hinner inte webbservern ändra HTTP-headern innan webbsidan skickas. (Som du ser i exemplet några stycken upp så kan man inte skicka nya HTTP-huvuden efter koden har börjat överföras.) PHP-koden kommer aldrig att vara synlig för besökaren.

Din HTML-sida bör nu se ut såhär:

<?php header('Content-Type: text/html; charset=utf-8'); ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
<title>Kolla, jag använder UTF-8!</title>
</head>
<body>
<p>Här skulle då sidan med lite konstiga tecken så som åäö vara.</p>

<p>Ser du detta?! ÖÄÅ?!</p>
</body>
</html>

Man skriver alltså först MIME-typen för webbsidan, följt av ett semikolon (;), som sedan följs av den teckenkodning man använder (charset=UTF-8 i exemplet). Det är viktigt att det alltid är i denna ordning med ; som avskiljare, annars kommer webbläsaren inte kunna tolka headern ordentligt.

Eftersom att XHTML bör ha en annan MIME-typ så byter man naturligtvis ut första raden mot detta om man använder XHTML:

<?php header('Content-Type: application/xhtml+xml; charset=UTF-8'); ?>

Vi kommer inte gå in djupare på vad PHP uträttar med denna kod eller hur HTTP fungerar. Vi får helt enkelt acceptera att det ser ut och fungerar såhär för tillfället, eftersom det skulle ta för lång tid att gå igenom det mer utförligt.

Lösningen för filer som lagras lokalt och för dig som inte kan ändra i severn

När du påbörjar din första webbsida är det inte troligt att du redan har en webbserver att konfigurera som vi gick igenom ovan. Eftersom man inte behöver transportera webbsidan när den lagras lokalt (”på din dator”) så är inte HTTP inblandat. Man får berätta för webbläsaren vilken teckenkodning man använder genom att skriva det i HTML-koden. Hur man går till väga skiljer sig beroende på om du använder HTML eller XHTML.

För HTML ska man använda sig av ett meta-element. Problemet här är att webbläsaren måste börja tolka koden utan att veta vilken teckenkodning det är innan den hittat meta-elementet. Man använder endast denna för sidor som lagras lokalt, till exempel när en besökare sparar ner din sida på sin disk. Det är även en fallback i specialfall när du varken har tillgång till att ändra serverinställningar eller serverskript.

Tänk även på att HTTP-huvudet Content-Type har högre prioritet än meta-elementet, så om dessa värden skiljer sig från varandra kommer webbläsaren använda sig av värdet den hittade i HTTP-huvudet. Webbläsaren kontrollerar alltid Content-Type först, och om charset-parametern saknas där använder den meta-elementet. Hur som helst ser det färdiga meta-elementet ut såhär och ska placeras så högt upp i head-elementet som möjligt, absolut före title:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">

<title>Kolla, jag använder UTF-8!</title>
</head>
<body>
<p>Här skulle då sidan med lite konstiga tecken så som åäö vara.</p>

<p>Ser du detta?! ÖÄÅ?!</p>;
</body>
</html>

Känner man sig lite modern och vill använda HTML 5 kan man istället för den långa raden ovan använda <meta charset="utf-8">. För XHTML används en så kallad XML-deklaration. Denna kommer ignoreras om inte XHTML-sidan skickas med korrekt MIME-typ, eftersom sidan som tidigare känt då kommer hanteras som HTML och nedanstående kodrad inte har någon betydelse i HTML.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Kolla, jag använder UTF-8!</title>
</head>

<body>
<p>En XHTML-sida med öäå, inte allt för ovanligt!</p>
</body>
</html>

Även XML-deklarationen har lägre prioritet än Content-Type, men som vi tidigare nämnt bör du inte inkludera charset-parametern i XHTML-dokuments Content-Type, utan du bör helt förlita dig på XML-deklarationen.

Åtgärder att vidta då Unicode inte är ett alternativ

Låt oss säga att du av någon anledning skulle vara inkapabel att använda en UTF-8 eller en teckenkodning med lika brett teckenutbud. Låt oss sedan fortsätta denna hemska tanke med att vi vill använda tecken ”utanför” vår teckenkodning. Hur ska vi då göra för att använda dessa tecken? Jo, vi har två alternativ: numeriska referenser och teckenentiteter.

Numeriska teckenreferenser

Till att börja med har vi två typer av numeriska teckenreferenser, decimala och hexadecimala. Syntaxen för den decimala versionen är &#nnnn; och det hexadecimala eländet &#xnnnn;. Själva talet refererar alltid, oberoende av vilken teckenkodning du använder på sidan, till kodpositionen i Unicode-teckenrepertoaren.

Teckenentiteter

Här används symboliska namn istället för tal, till exempel kan man använda &copy; för att infoga ett ©-tecken. Tursamt nog finns det generösa personer som sammanställt listor över de cirka 250 olika referenserna som du kan tänkas använda.

Övriga vanliga problem rörande teckenkodning

Man löser självklart inte alla problem genom att endast ändra värdena på alla dessa attribut på olika ställen, man måste förstås spara alla delar av webbsidan i den teckenkodingen man angivit. Detta görs oftast genom en inställning i din textredigerare. Hur man gör detta beror på vilken textredigerare man använder dig av; i vissa ”textredigerare” går det inte ens ställa in vilket du ska använda. I notepad++ (som vi rekommenderade i början av boken) gör man detta under Format → ”UTF-8 without BOM”. Vi går igenom lite längre ner varför du bör välja alternativet utan BOM.

Efter en snabb koll på teckenkodning kan du förhoppningsvis grunderna och förstår dig på en del av problemen som kan uppstå. Det finns personer som påstår att man inte behöver lära sig detta för att ”det inte har något med webbdesign att göra”, men sedan sitter de och tuggar fradga i frustration över att åäö inte fungerar på deras webbsida. Du får själv avgöra om du vill komma ihåg detta eller inte.

Vissa tecken visas inte som jag vill, till exempel renderas ”ä” som ”ä”

Det är inte säkert att ”ä” renderas på exakt samma sätt som i rubriken, det är bara ett exempel. Antagligen har du sparat ditt dokument med en annan teckenkodning än du berättar för webbläsaren. Du måste alltid spara filen i det formatet du talar om för webbläsaren att den är sparad i, annars blir det som du själv ser fel… Dubbelkontrollera så att du verkligen gjort rätt:

  1. Sparat filen med önskad teckenkodning, förslagsvis UTF-8.
  2. Kontrollera att Content-Type är satt till teckenkodningen du sparade filen i.
  3. Kontrollera att webbläsaren verkligen förstår vad du säger till den. I t.ex. webbläsaren Firefox ser du vilken teckenkodning den använder genom att gå till Visa ⇒ Kodning.
  4. Testa i olika webbläsare, är det kanske till och med din webbläsare som är trög och inte förstår vad du talar om för den? Fungerar det i vissa men inte andra? Fungerar det inte i någon alls är det antagligen ditt fel, annars kan det bero på en webbläsarbugg. Självklart ska det fungera i så många webbläsare som möljigt, men tänk på att väldigt gamla webbläsare kan sakna stöd för UTF-8. Du bör fundera på att uppdatera din webbläsare om det är så det ligger till.

XHTML och PHP-kollision

Om ägaren av servern inte tänkt efter riktigt när han eller hon ställde in hur webbservern och PHP ska fungera finns det en risk att något som kallas för short_open_tag är aktiverat. Denna inställning gör att XML-deklarationstarten, det vill säga <?, tolkas som en startpunkt för PHP istället. Men som tur är berör detta endast filer med ett filslut som förväntas innehålla PHP-kod, alltså främst filer med filslutet .php.

Om det inte är din server så är det inte mycket du kan göra åt detta, förutom att använda dig av PHP för att skriva ut din XML-deklaration. Detta görs genom följande kod (och det är inget vi kommer gå igenom noggrannare eftersom det kräver grundläggande kunskap inom PHP):

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>

Webbläsaren visar konstiga tecken i början av mitt dokument (BOM-problem)

Om din webbbläsare visar oönskade tecken, till exempel , eller en blank rad i början av ditt dokument så är det troligen någon som kallas för BOM (Byte Order Mark) som bråkar. Det beror troligen på att du inte specificerat rätt teckenkodning på de ställen vi gått igenom eller att du använder en mycket gammal webbläsare (dags att uppgradera!). Om det istället är tecken mitt i dokumentet beter sig oväntat beror det troligen på något annat; läs sammanfattningen nedan.

BOM talar om ifall texten är kodad i ”big endian”- eller ”little endian”-format. Det har att göra med hur byteordningen är upplagd. I big endian, eller rak byteordning som det också kallas, kommer den högsta byten först. I little endian, också kallad omvänd byteordning, kommer istället den lägsta byten först. Ett annat sätt att se på det är att kolla om MSB, most significant byte, kommer först eller sist. BOM är ett måste för UTF-16 och UTF-32, men är frivillig för UTF-8 eftersom UTF-8 inte har någon alternativ ordning av byten i sina tecken, vilket är vad BOM-signaturen talar om för webbläsaren.

BOM ställer till det speciellt med i skrivande stunds PHP-version och användandet av funktionen header, eftersom att den måste befinna sig först i filen för fungera. Med en BOM-signatur i början påstår PHP att det redan skickas information och den kan inte längre ändra i HTTP-huvudet. Lösningen är helt enkelt att spara filen som UTF-8 utan BOM. Förhoppningsvis finns en sådan inställning i din textredigerare, annars är den ända utvägen att byta mot en nyare med flera funktioner.

Min textredigerare vill inte koda om texten

Låt oss säga att du har en fil som redan är kodad i ISO-8859-1 och sedan vill omkoda den till UTF-8. Detta är naturligtvis ingen omöjlig uppgift, men kan strula ibland. Om vi tar ett exempel med notepad++ igen:

  1. Du öppnar filen som är kodad i ISO-8859-1.
  2. Du vill koda om filen till UTF-8 och väljer därför ”Format” ⇒ ”Encode in UTF-8 (without BOM)”.

Det låter kanske som ett smart drag, men nu visas istället dina före detta ”å” som ”䀵”. Varför? Jo, notepad++ byter bara teckenkodning, den omkodar inte tecknen. I ISO-8859-1 är ”å” 11100101 (decimalt: 229) skrivet binärt. Eftersom notepad++ inte omkodar filen så låter den 11100101 stå kvar. Sedan när programmet ska visa tecken i ett format som användaren kan förstå (läsbara tecken alltså) så kommer den nu istället tolka filen som UTF-8. Nu är inte 11100101 ”å” i UTF-8, utan någon annat spännande tecken visas. (”å” i UTF-8 är 1100001110100101.)

Så, hur ska man göra? Svaret varierar från textredigerare till textredigerar, men det finns vissa program som kan konvertera om filen från en teckenkodning till en annan. Om du använder Windows och notepad++ så kan du använda detta lite smålustiga trick:

  1. Ställ notepad++ i ett läge där alla tecknen syns på det sättet du önskar.
  2. Markera och klipp ut all text (Ctrl + A, Ctrl + X).
  3. Byt teckenkodning till den du egentligen vill ha, troligen UTF-8.
  4. Klipp in texten igen (Ctrl + V).

Sammanfattning

En kort att göra-lista för att se till att rätt teckenkodning används:

  1. Kom ihåg att verkligen spara din fil i UTF-8-format.
  2. Sätt Content-Type till MIME-typ; charset=teckenkodning på valfritt sätt.
  3. Lägg till ett meta-element med nödvändig information (eller en XML-deklaration om du använder XHTML) för att slippa onödiga problem. Detta är dock frivilligt; Content-Type är mycket viktigare.