Quelque chose dans votre code ne gère pas la chaîne comme UTF8. Cela pourrait être votre PHP/HTML, cela pourrait être dans votre connexion à la base de données, ou cela pourrait être la base de données elle-même - tout doit être défini comme UTF8 de manière cohérente, et si quelque chose ne l'est pas, la chaîne sera tronquée exactement comme vous voir lors du passage d'une limite UTF8/non-UTF8.
Je suppose que votre base de données est conforme à UTF8 - c'est le plus facile à vérifier. Notez que le classement peut être défini au niveau du serveur, au niveau de la base de données, au niveau de la table et au niveau de la colonne dans la table. La définition du classement UTF8 sur la colonne doit remplacer tout le reste pour le stockage, mais les autres seront toujours activés lors de la communication avec la base de données s'ils ne sont pas également UTF8. Si vous n'êtes pas sûr, définissez explicitement la connexion sur UTF8 après l'avoir ouverte :
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
Maintenant que votre base de données et votre connexion sont en UTF8, assurez-vous que votre page Web l'est également. Encore une fois, cela peut être défini à plusieurs endroits (.htaccess, php.ini). Si vous n'êtes pas sûr/n'y avez pas accès, remplacez simplement ce que PHP récupère par défaut en haut de votre page :
<?php ini_set('default_charset', 'UTF-8'); ?>
Notez que vous voulez ce qui précède dès le début, avant que tout texte ne soit sorti de votre page. Une fois que le texte est sorti, il est potentiellement trop tard pour essayer de spécifier un encodage - vous êtes peut-être déjà bloqué sur ce qui est par défaut sur votre serveur. Je répète également ceci dans mes en-têtes (peut-être exagéré) :
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
</head>
Et je le remplace sur les formulaires où je prends également des données :
<FORM NAME="utf8-test" METHOD="POST" ACTION="utf8-test.php" enctype="multipart/form-data" accept-charset="UTF-8">"
Pour être honnête, si vous avez défini l'encodage en haut, je crois comprendre que les autres remplacements ne sont pas nécessaires - mais je les garde quand même, car cela ne casse rien non plus, et je préfère simplement indiquer le encodage explicite, que de laisser le serveur faire des suppositions.
Enfin, vous avez mentionné que dans phpMyAdmin, vous avez inséré la chaîne et qu'elle ressemblait à ce que vous attendiez - êtes-vous sûr que les pages phpMyAdmin sont en UTF8 ? Je ne pense pas qu'ils le soient. Lorsque je stocke des données UTF8 à partir de mon code PHP, elles s'affichent comme des caractères 8 bits bruts dans phpMyAdmin. Si je prends la même chaîne et que je la stocke directement dans phpMyAdmin, elle a l'air "correcte". Je suppose donc que phpMyAdmin utilise le jeu de caractères par défaut de mon serveur local, pas nécessairement UTF8.
Par exemple, la chaîne suivante stockée à partir de ma page Web :
I can’t wait
Se lit comme ceci dans mon phpMyAdmin :
I can’t wait
Soyez donc prudent lorsque vous testez de cette façon, car vous ne savez pas vraiment quel encodage phpMyAdmin utilise pour l'affichage ou la connexion à la base de données.
Si vous rencontrez toujours des problèmes, essayez mon code ci-dessous. Je crée d'abord une table pour stocker le texte en 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 ;
Et voici du PHP pour le tester. Il prend essentiellement votre entrée sur un formulaire, vous renvoie cette entrée et stocke/récupère le texte de la base de données. Comme je l'ai dit, si vous affichez les données directement dans phpMyAdmin, vous constaterez peut-être qu'elles n'apparaissent pas ici, mais à travers la page ci-dessous, elles devraient toujours apparaître comme prévu, car la connexion à la page et à la base de données est verrouillée sur 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>