Autheur: Rob Hankel.
datum: 12 juni 2008
Als programmeur loop je wel eens tegen dingen aan welke niet duidelijk zijn gedocumenteerd.
Hieronder het relaas van de programmeur die in zijn opdracht heeft meegekregen een CMS
systeem te bouwen wat in meerdere talen te gebruiken is. Al snel zie je al die speciale tekens welke in de internationale talen gebruikt worden!
Een aantal daarvan kennen wij. Kijk hoe je makkelijk in PHP een overzicht genereert: speciale tekens in php.
Echter: die tekens zijn dus 'makkelijk'. Relatief gezien!
Dit zijn voorbeelden van vreemde tekens welke je ziet als het fout gaat:
® = ®
• = ·
ë = ë
ï = ï
’= ’
Indien correct de utf-8 headres worden meegegeven vanuit PHP dan zullen ook bovenstaande tekens correct worden weergegeven.
ze komen veelal foutief op beeld juist door verkeerd gebruik van de charset. De browser heeft die informatie nodig.
Een uitgebreidt UTF-8 verhaal kunt u op internet lezen (Engels, meertalig).
Ten einde correct speciale diakritische tekens weer te geven op een website zijn er de volgende richtlijnen:
- MySQL:
- De database zelf,
Collation: utf8_unicode_ci
- Tekstveld met speciale characters,
Collation: utf8_unicode_ci
- PHP connectie MySQL:
- opbouw connectie:
mysql_query("SET NAMES utf8");
- Test ook de variabelen in MySQL:
SHOW VARIABLES LIKE 'character%';
SHOW VARIABLES LIKE 'collation%';
--> Test bovenstaande Mysql Variabelen ook!
- PHP output naar HTML
- HTML code rechtstreeks uit de database naar HTML coderen met
$new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
(Uitvoer van dit voorbeeld is: <a href='test'>Test</a>)
- Voeg toe (in PHP):
header("Content-Type: text/html; charset=UTF-8");
- Maar ook (in HTML):
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- Codeer je formulier als volgt:
<form action="test.php" method="post" accept-charset="UTF8">
- PHP input uit HTML
- Controleer of Magic Quotes aanstaat. Dit maak je snel ongedaan door deze code altijd uit te voeren:
<?php
if ( get_magic_quotes_gpc() ) {
$_GET = array_map('stripslashes',$_GET);
$_POST = array_map('stripslashes',$_POST);
$_COOKIE = array_map('stripslashes',$_COOKIE);
}
?>
- Data welke nu uit je formulier komt sla je rechstreeks op in de database.
Omwille van veiligheidsredenen moet je nog de single quote van de query oplossen.
$sql = "UPDATE t SET txt='" . mysql_real_escape_string($_POST['veldnaam'], $conn) . "' WHERE id=12";
- Opletten in HTML
- Een formulierveld <INPUT NAME="veldnaam" VALUE="$waarde" />
Stel dat $waarde de volgende tekst bevat: 's morgens eerst een sterke bak "pleur"!?
De " (quote) zorgt ervoor dat het attribuut VALUE zijn tekst niet tussen quotes kan krijgen!
Gebruik daarom ENT_COMPAT om het "-teken te coderen in ".
Het formulierveld wordt als volgt in HTML uitgevoerd hierdoor:
<INPUT NAME="veldnaam" VALUE="'s morgens eerst een sterke bak "pleur"!" />
- Bij een textarea kun je ENT_NOQUOTES gebruiken, maar als je ENT_QUOTES aanhoudt gaat het ook goed.
- TESTEN
- De volgende tekst wordt gebruikt om te testen:
Iñtërnâtiônà lizætiøn 's morgens eerst een sterke bak "pleur"!
- VALKUIL
- Bovenstaande tekst komt OF uit een database, OF uit een bestand.
Het staat niet in dit PHP bestand, omdat een PHP bestand in ASCII (ANSI) indeling wordt opgeslagen op uw systeem.
Wilt u echt UTF-8 karakters in PHP opslaan dan moet u het PHP-bestand als UTF-8 opslaan. Dat geeft problemen!
- Niet echt een valkuil maar wel een detail om op te letten. Het lijkt er op dat de zin welke wordt gebruikt om te testen,
problemen geef met mysql_real_escape_string. Deze laatste doet zowel de " als de ' met een backslash!
Daarop geeft MySql dan een error. Dit betekent dat je de string dan zelf moet escapen met een replace functie.
- Let op:
mysql_client_encoding() geeft op de meeste computers latin1 terug.
Dit is (op het moment van schrijven) een BUG. Meerdere klachten heb ik in fora hierover gezien!
- Code
- Voor deze test is een database aangemaakt met phpmyadmin. Enige details:
Server version: 5.1.23-rc-community
MySQL client version: 5.0.22
MySQL connection collation: utf8_unicode_ci
CREATE TABLE IF NOT EXISTS `tbl_text` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Bekijk resultaten van UTF-8 uit de database, gemaakt op de test pagina.