Algo en su código no maneja la cadena como UTF8. Podría ser su PHP/HTML, podría estar en su conexión a la base de datos, o podría ser la propia base de datos:todo debe configurarse como UTF8 de manera consistente, y si algo no lo está, la cadena se truncará exactamente como usted ver al cruzar un límite UTF8/no UTF8.
Asumiré que su DB es compatible con UTF8, eso es lo más fácil de verificar. Tenga en cuenta que la intercalación se puede establecer en el nivel del servidor, el nivel de la base de datos, el nivel de la tabla y el nivel de la columna dentro de la tabla. La configuración de la intercalación UTF8 en la columna debería anular cualquier otra cosa para el almacenamiento, pero los demás aún se activarán cuando se hable con la base de datos si no son también UTF8. Si no está seguro, establezca explícitamente la conexión en UTF8 después de abrirla:
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
Ahora que su base de datos y su conexión son UTF8, asegúrese de que su página web también lo sea. Nuevamente, esto se puede configurar en más de un lugar (.htaccess, php.ini). Si no está seguro/no tiene acceso, simplemente anule lo que PHP esté seleccionando como predeterminado en la parte superior de su página:
<?php ini_set('default_charset', 'UTF-8'); ?>
Tenga en cuenta que desea lo anterior justo al principio, antes de que se emita cualquier texto desde su página. Una vez que se emite el texto, es potencialmente demasiado tarde para intentar especificar una codificación; es posible que ya esté bloqueado en lo que sea predeterminado en su servidor. Luego también repito esto en mis encabezados (posiblemente exagerado):
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
</head>
Y lo anulo en formularios donde también estoy tomando datos:
<FORM NAME="utf8-test" METHOD="POST" ACTION="utf8-test.php" enctype="multipart/form-data" accept-charset="UTF-8">"
Para ser honesto, si configuró la codificación en la parte superior, entiendo que las otras anulaciones no son necesarias, pero las mantengo de todos modos, porque tampoco rompe nada, y prefiero simplemente indicar el codificando explícitamente, que dejar que el servidor haga suposiciones.
Finalmente, mencionó que en phpMyAdmin insertó la cadena y se veía como se esperaba. ¿Está seguro de que las páginas de phpMyAdmin son UTF8? No creo que lo sean. Cuando almaceno datos UTF8 de mi código PHP, se ven como caracteres sin formato de 8 bits en phpMyAdmin. Si tomo la misma cadena y la almaceno directamente en phpMyAdmin, parece 'correcta'. Así que supongo que phpMyAdmin está usando el conjunto de caracteres predeterminado de mi servidor local, no necesariamente UTF8.
Por ejemplo, la siguiente cadena almacenada desde mi página web:
I can’t wait
Se lee así en mi phpMyAdmin:
I can’t wait
Así que tenga cuidado al probar de esa manera, ya que realmente no sabe qué codificación está usando phpMyAdmin para la visualización o la conexión a la base de datos.
Si aún tiene problemas, pruebe mi código a continuación. Primero creo una tabla para almacenar el texto 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 ;
Y aquí hay algo de PHP para probarlo. Básicamente, toma su entrada en un formulario, repite esa entrada y almacena/recupera el texto de la base de datos. Como dije, si ve los datos directamente en phpMyAdmin, es posible que no se vea bien allí, pero a través de la página a continuación siempre debería aparecer como se esperaba, debido a que la conexión de la página y la base de datos están bloqueadas en 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>