3

tengo un problema a la hora de registrar la letra Ñ en la base de datos MYSQL, no se con exactitud que tipo de cotejamiento utilizar ya que hay varios tuve que optar por 'utf8_spanish_ci' pero sigue saliendo este "ñ" en vez de la "Ñ".

Les adjunto un Print de pantalla de como se registra la letra Ñ en MYSQL y también el código PHP

Les adjunto un Print de pantalla de como se registra la letra Ñ en MYSQL

 <?php

   include_once'conexion.php';

   if(isset($_POST['registrar'])){

  $nombre  =$_POST['nom'];
   $apellido = $_POST['ape'];
  $gmail = $_POST['gmail'];

       $sql = "INSERT INTO registros(nombre_regisdb,apellido_regisdb,gmail)values('$nombre','$apellido','$gmail')";

$resul=$conexion->query($sql);

   if ($resul>0) {
    sleep(2);
    header('location: mensaje.php');
  }
 }

  ?>

  <html>

     <form action="<?php $_SERVER['PHP_SELF']; ?>" method="POST">
    <h1>registrarme</h1>
    <input placeholder="nombre" name="nom" type="text">
    <br>
    <br>
    <input placeholder="apellido" name="ape" type="text">
    <br>
    <br>
    <input placeholder="gmail" name="gmail" type="email">
    <br>
    <br>
    <input value="registrarme" name="registrar" type="submit">

   </form>

 </html>
kyle
  • 79
  • 1
  • 2
  • 8
  • El problema puede venir de que la codificación del HTML desde el cual tomas los datos para insertarlos está mal, [**te sugiero que revises esta respuesta**](https://es.stackoverflow.com/a/59510/29967) – A. Cedano May 21 '17 at 19:12
  • ¿Podrías compartir tu código de conexión a la base de datos? ¿Usas PDO o mysqli? Tengo más o menos claro lo que te ocurre, pero necesito más detalles para decir cómo solucionarlo en tu caso particular (PDO o mysqli). – OscarGarcia May 21 '17 at 19:28
  • utilizo MYSQLI. – kyle May 21 '17 at 19:34
  • @kyle , recuerda nombrar a las personas poniendo un @ delante. Si no es en una respuesta mía no me entero que ya has respondido a mi pregunta. Voy a redactar la respuesta y explicarte lo que te pasa. – OscarGarcia May 21 '17 at 19:49
  • Mil disculpas @oscarGarcia, agradecere mucho tu Respuesta. – kyle May 21 '17 at 19:59
  • Ya la he redactado, pruébala y me cuentas. Por cierto, los datos ya metidos en la base de datos se pueden arreglar, pero eso requeriría de código adicional, mi código te ayudará a que a partir de ahora todo se guarde correctamente. – OscarGarcia May 21 '17 at 20:15
  • de acuerdo @OscarGarcia probaré el código y te cuento. – kyle May 21 '17 at 20:24
  • Me falta un detalle aún, usar consultas preparadas. Estoy editando ahora mismo mi respuesta para agregarlas, la forma en la que lo haces es vulnerable a ataques de inyección de SQL y fallará si contiene comillas simples. – OscarGarcia May 21 '17 at 20:25

3 Answers3

1

Puedes hacer 3 cosas:

Para guardar en mysql:

Puede ser utf-8 o iso-8859-1 o buscar alguna latin...pero usa utf-8 de preferencia y pasa al paso 3 para la versión PHP.

Para mostrar (en HTML) agregar la meta:

<meta charset="iso-8859-1">

O...

<meta charset="utf-8">

Para guardar los valores codificarlos antes de que entren a la base de datos con:

htmlentities() [Documentación: http://php.net/manual/es/function.htmlentities.php] en PHP

Recuerda, la forma de recibir $hola = $_POST['algo']; es insegura debido a que de esta manera pueden inyectar código HTML y se guardaría y al imprimir podrían aprovechar ese error de seguridad y demás, te es más conveniente limpiar el valor.

Saludos.

Asfo
  • 177
  • 1
  • 8
  • Solo quiero guardar los registros en la base de datos, con lo de utf-8 es en el código php o en la selección de tipos de cotejamiento en la base de datos?. No quiero mostrar los registros en HTML y acerca de htmlentities con esto se pueden evitar las inyecciones SQL verdad. – kyle May 21 '17 at 19:21
  • Usar `htmlentities` debe usarse únicamente para enviar información al navegador, y yo prefiero usar `htmlspecialchars`. Si lo usas para guardar datos en una base de datos no podrás usar funciones de mayúsculas, minúsculas, búsquedas de texto, etc. – OscarGarcia May 21 '17 at 20:18
1

Para que tu aplicación trabaje a todos los niveles a UTF-8 debes comprobar que:

  • Tu servidor debe devolver la cabecera Content-Type: text/html; charset=utf-8 ya sea generada desde el propio script PHP (con header('Content-type: text/html; charset=utf-8')) o desde el servidor web (AddType o AddCharset en la configuración de apache, por ejemplo).
  • Las locales de PHP también deben soportar UTF-8. Casi todos los sistemas Linux modernos tienen por defecto en_US.UTF-8 o es_ES.UTF-8 o equivalente. Si el que viene configurado por defecto es diferente deberás cambiarlo con setlocale(LC_ALL, 'es_ES.UTF-8'). Usa locale -a para obtener el listado disponible.
  • Tu HTML debe tener definido el juego de caracteres usando la etiqueta <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> en compatibilidad con HTML4 y/o <meta charset="utf-8"> usando HTML5.
  • Tus tablas en el servidor MySQL deben (aunque no es necesario) usar el cotejamiento (utf8_spanish_ci).
  • La conexión con el servidor MySQL debe usar codificación UTF-8 usando SET CHARACTER SET utf8 a través de una llamada a mysqli::set_charset() en el caso de usar mysqli.

Aunque las dos primeras pueden ser complementarias (la definición dentro del HTML suele tener preferencia y la cabecera HTTP suele usarse en ausencia de ella), es recomendable usar ambas para que evitar problemas.

Los dos últimos igual, los datos podrían estar almacenados en un cotejamiento diferente siempre que se especifique correctamente el protocolo de comunicaciones entre cliente y servidor, el servidor haría el trabajo de conversión de juegos de caracteres, pero es importante que si usamos consultas SQL con cadenas de caracteres en UTF-8 definamos ésto con el método propuesto.

Es equivalente a hacer:

SET character_set_client = 'utf-8';
SET character_set_results = 'utf-8';
SET collation_connection = @@collation_database;

Por lo que usar el cotejamiento correcto en base de datos y tablas nos ahorrará hacer más modificaciones, aunque sea opcional.

Ejemplo de código PHP/HTML correcto:

<?php
header('Content-type: text/html; charset=utf-8');

include_once 'conexion.php';
/* Ésto sería  mejor meterlo dentro de "conexión.php" */
if ($conexion->set_charset('utf8') === false) {
  die('Error: ' .  $conexion->error);
}

if(isset($_POST['registrar'])) {
  $nombre = $_POST['nom'];
  $apellido = $_POST['ape'];
  $gmail = $_POST['gmail'];

  $consulta = $conexion->prepare('
    INSERT INTO registros (
      nombre_regisdb, 
      apellido_regisdb,
      gmail
    ) VALUES (
      ?,
      ?,
      ?
    )
  ');
  if ($consulta === false) {
    die('Error en la consulta: ' . $conexion->error);
  }
  $consulta->bind_param(
    'sss',
    $_POST['nom'],
    $_POST['ape'],
    $_POST['gmail']
  );
  /* Esto cambia un poco el resto del HTML, pero bueno */
  if ($consulta->execute() !== false) {
    header('location: mensaje.php');
  } else {
    die('Error');
  }
}
?><!doctype html>
<html lang=es>
  <head>
    <meta charset="utf-8">
    <title>Título</title>
  </head>
  <body>
    ...
  </body>
</html>
OscarGarcia
  • 26,999
  • 3
  • 26
  • 61
  • 1
    Genial, me fue de lujo, si funciona, gracias hermano estoy muy agradecido por tu respuesta. Stackoverflow es de lujo. – kyle May 21 '17 at 20:35
  • Revisa cómo haces la inserción de datos, te he puesto un ejemplo con mysqli y sus consultas preparadas, aunque yo suelo usar PDO y no tengo demasiada práctica con mysqli espero que te sirva de orientación. – OscarGarcia May 21 '17 at 20:36
  • el código 'prepare' es para evitar las inyecciones sql verdad?. – kyle May 21 '17 at 20:36
  • Es para realizar consultas preparadas. Es la forma correcta de agregar datos a una consulta SQL, pero también podrías haber usado http://php.net/mysqli.real-escape-string , pero ésto es más cómodo y se lee mejor el código SQL. Las consultas preparadas también sirven para definir el SQL una única vez y luego ejecutar la consulta múltiples veces con diferentes datos. En mysqli en particular también te permite relacionar campos con variables de PHP. – OscarGarcia May 21 '17 at 20:38
  • Genial, gracias @OscarGarcia. – kyle May 21 '17 at 20:40
0

Además de lo que te han mencionado antes , es muy importante (y la mayor parte de las veces el problema) que el archivo .php esté guardado en formato UTF-8 y no en ANSI. Las veces que me he encontrado este problema, se ha solucionado simplemente cambiando el formato del archivo.

No sé qué editor usas, pero en la mayoría este cambio es trivial. Si no tienes un editor que lo haga, te sugiero Notepad++.

macl
  • 101
  • 1
  • Hola @macl, utilizo sublimetext como editor de texto. Gracias por tu respuesta. – kyle May 21 '17 at 20:39
  • Hola @kyle, yo también ;-) En sublimetext tienes la opción "Save with encoding", donde puedes elegir UTF-8 (la primera opción en mi caso). – macl May 21 '17 at 20:40
  • Si exacto acabo de comprobarlo. ^_^ Gracias. – kyle May 21 '17 at 20:43