Autor
|
Tema: [Pregunta]: Detectar acentos en consulta (Leído 8,098 veces)
|
Leguim
Desconectado
Mensajes: 720
|
Buenos días! Este es un tema que ya lo publique creo ya hace 2 meses aproximadamente no me acuerdo bien, en fin lo que me pasaba era que digamos tenía un buscador donde naturalmente se esperaba recibir una cadena de texto la cual serviría para buscar coincidencias dentro de una consulta (LIKE %$busqueda%). Después de pasar toda pero toda mi base de datos a 'utf8_spanish_ci' y hacer una re-configuración y mejoras al 100%, en relación a este problema nada cambió sigue sin detectar los acentos. Mi documento html tiene utf8, mi base de datos esta en utf8_spanish_ci, y no se que otra cosa tengo que cambiar la verdad, vi en otros temas que se debe poner set_charset pero también se dice que eso es una mala práctica. WHERE CONCAT(name, ' ', surname) LIKE '%".($search)."%'
|
|
|
En línea
|
|
|
|
EdePC
|
Saludos, - Que raro, he estado probando y esto me funciona perfecto con acentos, por ejemplo pongo: ciá y me muestra a Salomé García<form action="#" method="post"> <input type="text" name="busqueda" autocomplete="off"> <input type="submit" value="Buscar"> </form> <?php $busqueda = isset($_POST['busqueda']) ? $_POST['busqueda'] : ''; $con = new PDO("mysql:host=127.0.0.1;dbname=pers", "root", "root"); $sql = "SELECT name, surname FROM persons WHERE CONCAT(name, ' ', surname) LIKE '%$busqueda%'"; foreach ( $con->query($sql) as $row ) { echo $row['name'] . ' ' . $row['surname'] . '<br>'; } ?>
CREATE DATABASE pers; USE pers; CREATE TABLE persons ( id_person INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), surname VARCHAR(20) ); INSERT INTO persons VALUES ( NULL, 'Álvaro', 'Díaz' ), ( NULL, 'Inés' , 'López' ), ( NULL, 'René' , 'Guzmán');
- No he echo nada raro, ni configurado nada en MySQL (MariaDB), ni puesto utf-8 en nungún lugar, todo automático. - Si le hago un Dump a mi base de datos obtengo: -- MySQL dump 10.17 Distrib 10.3.17-MariaDB, for Win32 (AMD64) -- -- Host: localhost Database: pers -- ------------------------------------------------------ -- Server version 10.3.17-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `persons` -- DROP TABLE IF EXISTS `persons`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `persons` ( `id_person` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(20) DEFAULT NULL, `surname` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id_person`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */;
- Veo que usa InnoDB y utf8 por defecto. Supongo que por defecto todo debería de andar bien. Aquí he encontrado algo más de documentación que quizá debas revisar: https://www.baulphp.com/pdo-mysql-utf-8-caracteres-especiales-en-php/
|
|
|
En línea
|
|
|
|
MinusFour
|
Te diría que hicieras un dump de la tabla donde tienes los datos problema pero no estoy muy seguro de que la información que acabe aquí sea exactamente la que tienes en tu base de datos. Sobre todo con el típico copia y pega. Porque tu copias un string como: "Conexión" en el foro directamente de un documento en WP1252 o ISO-8859 que abriste de sublime o notepad++ por ejemplo, nosotros vamos a poder ver "Conexión" pero no el encoding que usaste. Pero si subes el archivo del dump en algún lado (que no haga nada raro con el charset) entonces podemos ver el encoding en el que está. Los dumps de hoy en día por lo general los recogen los editores correctamente, muy probablemente vengan con BOMs o similar. Entonces si tu abres el archivo y no ves nada raro, es muy probable que el encoding este correcto. Si empiezas a ver cosas como: "Conexi?n" en tu dump entonces hay problemas. Si todo se ve bien, como quiera puede haber problemas si tu editor está leyendo el archivo en otro encoding que no sea utf8. No es extraño que pudiera pasar esto porque UTF-8 y otros encodings pueden confundirse porque la mitad de los encodings que se utilizan son los mismos. Técnicamente, un archivo que solo usa caracteres ASCII puede ser leido perfectamente tanto en UTF-8 como en WP1252 o ISO-8859. Son indistinguibles. Pero cuando empiezas a usar cosas que no son ASCII ahí es cuando el editor de texto puede hacer conjeturas acerca del encoding. Si quieres estar totalmente seguro que la información de tu DUMP este correctamente en UTF-8 tienes que decirle al editor que abra el archivo con ese encoding. Y todo esto es para poder cerciorarse que lo que tienes en tu base de datos es UTF-8. Si crees que necesitas utilizar set_charset, revisa el charset de tu conexión:
Si imprime utf8 todo bien, si imprime algo como latin1 o similar entonces quizás si necesitas usar mysqli_set_charset. También puedes configurar tu servidor para que utilice un charset por defecto en las conexiones: ;porfavor no copiar el [mysqld], buscarlo en el archivo de configuración ;esta de referencia [mysqld] character_set_server=utf8 collation-server=utf8_spanish_ci
El character_set_server no es necesario si usas MySQL arriba de 8.0 porque ese es el valor por defecto (técnicamente, utf8mb4)
|
|
« Última modificación: 27 Agosto 2019, 02:16 am por MinusFour »
|
En línea
|
|
|
|
Leguim
Desconectado
Mensajes: 720
|
Hola! ya cambié algunas cosas, revise las cosas que me dijeron primero revisar el editor si guarda en el encoding utf8 que estaba bien, luego editar mysql la collation en ese archivo que estaba en utf8_uniqode_ci y lo cambie a utf8_spanish_ci, pero sigue igual lo que no se ahora es hacer un dump...
No se si sea relevante pero digamos un nombre el mio por ejemplo si le pones la i con acento se vería así en la base de datos:
MÃguel y no Míguel, me imagino que esto esta bien porque me codifica a utf8 pero quería señalarlo.
Gracias a los dos!
|
|
« Última modificación: 26 Agosto 2019, 18:09 pm por MiguelCanellas »
|
En línea
|
|
|
|
MinusFour
|
Entonces si tienes un problema con la información en la base de datos. Yo diría que la información que estás enviando si es UTF-8 pero está siendo codificada en otro encoding en otro lado, posiblemente en la conexión entre tu servidor SQL y cliente SQL por lo que me dices. El hexadecimal de la cadena "Míguel" en UTF-8 es: 0x4d 0xc3 0xad 0x67 0x75 0x65 0x6c Para 5 de los 7 bytes, la traducción es bastante simple, los puedes buscar en una tabla ASCII. Los únicos valores que no te vas a encontrar en la tabla son: 0xc3 y 0xad porque no son ASCII. Estos 2 bytes, representan un solo carácter en UTF-8, la i latina pequeña con acento agudo ( í ). ¿Pero que pasa cuando se usa otro encoding? Vamos a ver con WP 1252 (uno de los más comunes): Resulta ser que en WP-1252 los caracteres cada uno son de 1 byte. Por lo que tenemos 2 caracteres. Uno de ellos es: Ã y el otro es el carácter invisible SHY. Lo que significa que en lugar de tener una í , tenemos Ã<SHY>. SHY no se imprime por lo que acabamos con MÃguel en lugar de Miguel. PD. Me he equivocado con el nombre del encoding, en mi mente lo tengo como Windows Pages 1252 pero realmente es Code Page 1252 o Windows 1252.
|
|
|
En línea
|
|
|
|
Leguim
Desconectado
Mensajes: 720
|
No creo que te haya entendido muy bien jeje pero en base a lo que te pude entender hice esto. function Buscar_Usuarios_Ajax($search) { $con = Conexion("root", ""); echo $search; // imprimo la busqueda (texto) echo $search; // imprimo la busqueda (texto) pero codificada a utf8 $consulta = $con->prepare("SELECT id_user, name, surname, avatar FROM usuarios WHERE CONCAT(name, ' ', surname) LIKE '%".($search)."%' ORDER BY CONCAT(name, ' ', surname) ASC LIMIT 6"); $consulta->execute(); $resultados = $consulta->fetchAll(); echo $resultados[0]['name']; // imprimo el nombre encontrado return $resultados; }
me devuelve si escribo "Míguel" echo = "Míguel" echo = "MÃguel" naturalmente no va encontrar resultados pero digamos si escribo "M" antes de poner una i sin acento ya que en la base de datos existe "Míguel" pero se almacena "MÃguel" echo "M" echo "M" echo "Míguel" // sería el resultado obtenido o que se muestra de igual forma sigue sin funcionar y en breve me parece que va a pasar esto:
|
|
« Última modificación: 27 Agosto 2019, 00:30 am por MiguelCanellas »
|
En línea
|
|
|
|
EdePC
|
- Para ser más "crudos" puedes usar un Editor Hexadecimal, por ejemplo el gratuito HXD: https://mh-nexus.de/downloads/HxDSetup.zip- Luego te diriges a tu carpeta \mysql\data\pers\ donde pers coincide con el nombre de mi base de datos. - Abres (o arrastras a HxD) el fichero db.opt con HxD, ahí debe de decir el CharSet que usa tu base de datos, en mi caso tiene: Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 64 65 66 61 75 6C 74 2D 63 68 61 72 61 63 74 65 default-characte 00000010 72 2D 73 65 74 3D 75 74 66 38 0A 64 65 66 61 75 r-set=utf8.defau 00000020 6C 74 2D 63 6F 6C 6C 61 74 69 6F 6E 3D 75 74 66 lt-collation=utf 00000030 38 5F 67 65 6E 65 72 61 6C 5F 63 69 0A 8_general_ci.
- Luego, puedes abrir también los ficheros que corresponden a cada una de tus tablas, en mi caso: persons.idb, buscando un poco puedes encontrar como se ha almacenado tus datos en bruto, por ejemplo en mi caso: Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0000C090 00 C3 81 6C 76 61 72 6F 44 C3 AD 61 7A 06 05 00 .Ã.lvaroDÃ.az... 0000C0A0 00 00 18 00 24 80 00 00 02 00 00 00 00 00 00 80 ....$€.........€ 0000C0B0 00 00 00 00 00 00 49 6E C3 A9 73 4C C3 B3 70 65 ......InésLópe 0000C0C0 7A 07 05 00 00 00 20 00 25 80 00 00 03 00 00 00 z..... .%€...... 0000C0D0 00 00 00 80 00 00 00 00 00 00 52 65 6E C3 A9 47 ...€......RenéG 0000C0E0 75 7A 6D C3 A1 6E 07 07 00 00 00 28 FF 82 80 00 uzmán.....(ÿ‚€. 0000C0F0 00 04 00 00 00 00 00 00 80 00 00 00 00 00 00 53 ........€......S 0000C100 61 6C 6F 6D C3 A9 47 61 72 63 C3 AD 61 00 00 00 aloméGarcÃ.a...
- Esos son los datos para: Álvaro Díaz Inés López René Guzmán Salomé García
|
|
|
En línea
|
|
|
|
MinusFour
|
Otra cosa que tienes que estar seguro que este correcto es el charset de la base de datos. No lo confundas con el tipo de colación, la base de datos también tiene que estar en UTF-8.Me equivoco, si la colación es UTF8, tu base de datos también debería tiene ese charset. Es casi seguro que sea un problema con la conexión. No probaste con el primer código que te di?
¿Esto te regresa utf8?
|
|
« Última modificación: 27 Agosto 2019, 02:16 am por MinusFour »
|
En línea
|
|
|
|
Leguim
Desconectado
Mensajes: 720
|
Sería algo así, si ya se soy algo duro para entender function Conexion($user, $pass) { try { $con = new PDO('mysql:host=localhost;dbname=basedatos', $user, $pass); $con->character_set_name(); return $con; } catch(PDOException $e) { return $e->getMessage(); } }
Porque la manera en la que lo puse da errores, también probé tal y como me lo pasaste mysql_chararacter_set_name($mysql); pero da el error de que la función no existe (la variable $mysql la adapte por supuesto) EDIT: recien me di cuenta que que era mysqli_ y no mysql_ viendo el manual de php me di cuenta nose como no pude ver la i en la función que mandaste, igual ahora me da un warning "mysqli_character_set_name expects parameter 1 to be mysqli, object given in on line 1301" function Buscar_Usuarios_Ajax($search) { $con = Conexion("root", ""); $consulta = $con->prepare("SELECT id_user, name, surname, avatar FROM usuarios WHERE CONCAT(name, ' ', surname) LIKE '%".($search)."%' ORDER BY CONCAT(name, ' ', surname) ASC LIMIT 6"); $consulta->execute(); $resultados = $consulta->fetchAll(); return $resultados; }
|
|
« Última modificación: 27 Agosto 2019, 02:21 am por MiguelCanellas »
|
En línea
|
|
|
|
MinusFour
|
Sería algo así, si ya se soy algo duro para entender function Conexion($user, $pass) { try { $con = new PDO('mysql:host=localhost;dbname=basedatos', $user, $pass); $con->character_set_name(); return $con; } catch(PDOException $e) { return $e->getMessage(); } }
Porque la manera en la que lo puse da errores, también probé tal y como me lo pasaste mysql_chararacter_set_name($mysql); pero da el error de que la función no existe (la variable $mysql la adapte por supuesto) Perdón tenía el nombre mal no es mysql, es mysqli. ¿Estás usando PDO en lugar de MySQLi? Tenía entendido que estabas usando MySQLi. Bueno, de todas formas, si has puesto la configuración que he puesto antes, no debería importar que driver estes utilizando. PDO es más genérico, si quieres revisar que charset estás utilizando desde PDO puedes hacer una query desde PDO, la query es: SELECT @@character_set_client;
Si el charset de la conexión es el culpable, vas a tener que re insertar la información correctamente. Pero es importante que revises el charset que usa tu conexión antes de re insertar.
|
|
« Última modificación: 27 Agosto 2019, 02:27 am por MinusFour »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Software para detectar fallas de hardware en movil [Consulta ]
Dispositivos Móviles (PDA's, Smartphones, Tablets)
|
Megan
|
0
|
13,965
|
12 Enero 2012, 20:37 pm
por Megan
|
|
|
Pregunta bastante sencilla: Acentos y comillas en Batch
Scripting
|
z3nth10n
|
9
|
7,333
|
24 Mayo 2012, 21:02 pm
por z3nth10n
|
|
|
[Pregunta]: Detectar un click sobre un elemento
Desarrollo Web
|
Leguim
|
7
|
2,831
|
31 Enero 2019, 05:31 am
por Leguim
|
|
|
[Pregunta]: Detectar cuando se presiona determinada tecla
Desarrollo Web
|
Leguim
|
4
|
2,392
|
17 Marzo 2019, 04:03 am
por #!drvy
|
|
|
[Pregunta]: ¿Como puedo buscar un texto sin importar sus acentos?
Desarrollo Web
|
Leguim
|
2
|
2,069
|
18 Julio 2019, 09:43 am
por #!drvy
|
|