Něco ve vašem kódu nezpracovává řetězec jako UTF8. Může to být vaše PHP/HTML, může to být ve vašem připojení k DB, nebo to může být samotná DB – vše musí být konzistentně nastaveno jako UTF8, a pokud něco není, řetězec se zkrátí přesně tak, jak vy viz při přechodu přes hranici UTF8/non-UTF8.
Předpokládám, že vaše DB je kompatibilní s UTF8 - to je nejjednodušší zkontrolovat. Všimněte si, že řazení lze nastavit na úrovni serveru, databáze, tabulky a sloupce v tabulce. Nastavení řazení UTF8 ve sloupci by mělo přepsat cokoli jiného pro úložiště, ale ostatní budou při hovoru s DB stále fungovat, pokud také nemají UTF8. Pokud si nejste jisti, po otevření výslovně nastavte připojení na UTF8:
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
Nyní je vaše databáze a připojení UTF8, ujistěte se, že vaše webová stránka je také. Opět to lze nastavit na více místech (.htaccess, php.ini). Pokud si nejste jisti / nemáte přístup, jednoduše přepište vše, co PHP shromažďuje jako výchozí v horní části stránky:
<?php ini_set('default_charset', 'UTF-8'); ?>
Všimněte si, že výše uvedené požadujete hned na začátku, než bude z vaší stránky vytištěn jakýkoli text. Jakmile se text dostane na výstup, je potenciálně příliš pozdě na to, abyste se pokusili zadat kódování - můžete být již uzamčeni na cokoli, co je na vašem serveru výchozí. Také to pak opakuji ve svých hlavičkách (možná přehnaně):
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
</head>
A přepisuji to ve formulářích, kde také beru data:
<FORM NAME="utf8-test" METHOD="POST" ACTION="utf8-test.php" enctype="multipart/form-data" accept-charset="UTF-8">"
Abych byl upřímný, pokud jste nastavili kódování nahoře, chápu to tak, že ostatní přepisy nejsou vyžadovány - ale stejně je ponechám, protože to také nic nenarušuje a raději bych uvedl explicitně zakódovat, než nechat server, aby udělal předpoklady.
Nakonec jste zmínil, že v phpMyAdmin jste vložili řetězec a vypadalo to podle očekávání - jste si však jisti, že stránky phpMyAdmin jsou UTF8? Myslím, že nejsou. Když uložím data UTF8 z mého kódu PHP, zobrazí se v phpMyAdmin jako nezpracované 8bitové znaky. Pokud vezmu stejný řetězec a uložím ho přímo do phpMyAdmin, vypadá to „správně“. Takže předpokládám, že phpMyAdmin používá výchozí znakovou sadu mého místního serveru, ne nutně UTF8.
Například následující řetězec uložený z mé webové stránky:
I can’t wait
V mém phpMyAdmin se čte takto:
I can’t wait
Při testování tímto způsobem buďte opatrní, protože ve skutečnosti nevíte, jaké kódování phpMyAdmin používá pro zobrazení nebo připojení k databázi.
Pokud máte stále problémy, vyzkoušejte můj kód níže. Nejprve vytvořím tabulku pro uložení textu v UTF8:
CREATE TABLE IF NOT EXISTS `utf8_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`my_text` varchar(8000) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
A tady je nějaké PHP na otestování. V podstatě převezme váš vstup na formuláři, odešle jej zpět na vás a uloží/načte text z DB. Jak jsem řekl, pokud si data prohlížíte přímo v phpMyAdmin, možná zjistíte, že tam nevypadají správně, ale na níže uvedené stránce by se měla vždy zobrazit podle očekávání, protože spojení stránky a databáze je uzamčeno na UTF8.
<?php
// Override whatever is set in php.ini
ini_set('default_charset', 'UTF-8');
// The following should not be required with the above override
//header('Content-Type:text/html; charset=UTF-8');
// Open the database
$dbh = new PDO('mysql:dbname=utf8db;host=127.0.0.1;charset=utf8', 'root', 'password');
// Set the connection to UTF8
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
// Tell MySql to do the parameter replacement, not PDO
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// Throw exceptions (and break the code) if a query is bad
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$id = 0;
if (isset($_POST["StoreText"]))
{
$stmt = $dbh->prepare('INSERT INTO utf8_test (my_text) VALUES (:my_text)');
$stmt->execute(array(':my_text' => $_POST['my_text']));
$id = $dbh->lastInsertId();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional/EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<title>UTF-8 Test</title>
</head>
<body>
<?php
// If something was posted, output it
if (isset($_POST['my_text']))
{
echo "POSTED<br>\n";
echo $_POST['my_text'] . "<br>\n";
}
// If something was written to the database, read it back, and output it
if ($id > 0)
{
$stmt = $dbh->prepare('SELECT my_text FROM utf8_test WHERE id = :id');
$stmt->execute(array(':id' => $id));
if ($result = $stmt->fetch())
{
echo "STORED<br>\n";
echo $result['my_text'] . "<br>\n";
}
}
// Create a form to take some user input
echo "<FORM NAME=\"utf8-test\" METHOD=\"POST\" ACTION=\"utf8-test.php\" enctype=\"multipart/form-data\" accept-charset=\"UTF-8\">";
echo "<br>";
echo "<textarea name=\"my_text\" rows=\"20\" cols=\"90\">";
// If something was posted, include it on the form
if (isset($_POST['my_text']))
{
echo $_POST['my_text'];
}
echo "</textarea>";
echo "<br>";
echo "<INPUT TYPE = \"Submit\" Name = \"StoreText\" VALUE=\"Store It\" />";
echo "</FORM>";
?>
<br>
</body>
</html>