Qualcosa nel tuo codice non gestisce la stringa come UTF8. Potrebbe essere il tuo PHP/HTML, potrebbe essere nella tua connessione al DB o potrebbe essere il DB stesso:tutto deve essere impostato come UTF8 in modo coerente e, se qualcosa non lo è, la stringa verrà troncata esattamente come te vedere quando si passa attraverso un confine UTF8/non UTF8.
Presumo che il tuo DB sia conforme a UTF8:è più facile da controllare. Si noti che le regole di confronto possono essere impostate a livello di server, di database, di tabella e di colonna all'interno della tabella. L'impostazione delle regole di confronto UTF8 sulla colonna dovrebbe sovrascrivere qualsiasi altra cosa per l'archiviazione, ma le altre partiranno comunque quando parlano con il DB se non sono anche UTF8. Se non sei sicuro, imposta esplicitamente la connessione su UTF8 dopo averlo aperto:
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
Ora il tuo DB e la tua connessione sono UTF8, assicurati che lo sia anche la tua pagina web. Anche in questo caso, questo può essere impostato in più di un posto (.htaccess, php.ini). Se non sei sicuro/non disponi dell'accesso, sostituisci semplicemente qualsiasi PHP raccolga come predefinito nella parte superiore della tua pagina:
<?php ini_set('default_charset', 'UTF-8'); ?>
Nota che vuoi quanto sopra proprio all'inizio, prima che qualsiasi testo venga emesso dalla tua pagina. Una volta che il testo viene emesso, è potenzialmente troppo tardi per provare a specificare una codifica:potresti già essere bloccato in qualsiasi cosa sia predefinita sul tuo server. Lo ripeto anche nelle mie intestazioni (possibilmente eccessivo):
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
</head>
E lo sovrascrivo anche sui moduli in cui sto prendendo dati:
<FORM NAME="utf8-test" METHOD="POST" ACTION="utf8-test.php" enctype="multipart/form-data" accept-charset="UTF-8">"
Ad essere onesti, se hai impostato la codifica in alto, la mia comprensione è che le altre sostituzioni non sono richieste, ma le conservo comunque, perché non si rompe nulla e preferirei semplicemente affermare codificare in modo esplicito, quindi lasciare che il server faccia ipotesi.
Infine, hai menzionato che in phpMyAdmin hai inserito la stringa e sembrava come previsto - sei sicuro che le pagine di phpMyAdmin siano UTF8? Non credo che lo siano. Quando memorizzo i dati UTF8 dal mio codice PHP, vengono visualizzati come caratteri grezzi a 8 bit in phpMyAdmin. Se prendo la stessa stringa e la memorizzo direttamente in phpMyAdmin, sembra "corretto". Quindi suppongo che phpMyAdmin stia utilizzando il set di caratteri predefinito del mio server locale, non necessariamente UTF8.
Ad esempio, la seguente stringa memorizzata dalla mia pagina web:
I can¹t wait
Si legge così nel mio phpMyAdmin:
I can’t wait
Quindi fai attenzione quando esegui il test in questo modo, poiché non sai davvero quale codifica sta utilizzando phpMyAdmin per la visualizzazione o la connessione DB.
Se i problemi persistono, prova il mio codice qui sotto. Per prima cosa creo una tabella per memorizzare il testo in 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 ;
Ed ecco un po' di PHP per testarlo. Fondamentalmente prende il tuo input su un modulo, fa eco a quell'input e memorizza/recupera il testo dal DB. Come ho detto, se visualizzi i dati direttamente in phpMyAdmin, potresti scoprire che non sembra proprio lì, ma attraverso la pagina sottostante dovrebbe sempre apparire come previsto, poiché la pagina e la connessione db sono entrambe bloccate su 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>