utf8 set_charset name mysqli_query mysql_set_charset charset acentos php mysql character-encoding mysqli

set_charset - set charset php



una forma permanente de hacer mysqli-> set_charset()? (2)

después de configurar todas las opciones de archivo de configuración y tiempo de ejecución para el conjunto de caracteres que puedo encontrar en utf-8, las nuevas conexiones mysqli hechas con php todavía tienen su conjunto de caracteres latin1, lo que efectivamente significa que $mysqli->set_charset(''utf8'') llamar a $mysqli->set_charset(''utf8'') cada vez que me conecto.

$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); if ($mysqli->connect_error) err_handle("mysql connect error({$mysqli->connect_errno})."); if (!$mysqli->set_charset("utf8")) err_handle("db error({$mysqli->errno}).");

Me pregunto si hay una forma permanente de hacer esto.

Problema similar fue encontrado en este post .

una consulta " show variables like ''character_set%'' " en el servidor mysql antes de llamar a $mysqli->set_charset(''utf8'') muestra:
(esta parte fue ambigua en las revoluciones anteriores)

character_set_client latin1 character_set_connection latin1 character_set_database utf8 character_set_filesystem binary character_set_results latin1 character_set_server utf8 character_set_system utf8

el juego de caracteres del cliente, la conexión y los resultados solo se puede cambiar a utf8 con $mysqli->set_charset(''utf8'') en tiempo de ejecución. después de eso se muestra:

character_set_client utf8 character_set_connection utf8 character_set_database utf8 character_set_filesystem binary character_set_results utf8 character_set_server utf8 character_set_system utf8

yo tengo

default_charset = "utf-8"

establecido en php.ini, y

[client] default-character-set=utf8 ... [mysqld] ## This option is deprecated in favor of --character-set-server. #default-character-set=utf8

establecido en my.cnf.

el conjunto de caracteres predeterminado para mis tablas también es utf8.

Parece que las opciones "[cliente]" solo afectan la herramienta cmd "mysql" y no tienen nada que ver con php.

el valor de retorno de $mysqli->character_set_name() siempre es latin1 no importa lo que haga, hasta que se $mysqli->set_charset(''utf8'') .

Supongo que "latin1" es una cosa de mysql, ya que no puedo recordar nada más que por defecto sea "latin1" en mi sistema.

^ actualización: de acuerdo con el manual de mysql 9.1.4 , 9.1.5 y 5.1.3 , el cliente debe proporcionar character_set_client . Supongo que php no lo proporciona en la conexión y mysql usa el conjunto de caracteres latín1 .

Estoy ejecutando php 5.3 en debian wheezy con mysql 5.1.

¿cualquier sugerencia?

Actualizado con información de los comentarios:

Olvidé mencionar la directiva skip-character-set-client-handshake y por qué me resistí a usarla.

a primera vista, pensé que ignorar el saludo podría resultar en la situación de que el cliente habla latin1 mientras el servidor habla utf8 . ¿Cómo convierte el servidor la cadena de caracteres charset character_set_client a character_set_server sin saber el charset actualmente en uso?

corrígeme si me equivoco, por favor. Voy a experimentar con esta configuración más tarde hoy para ver si funciona.

Actualizado con workaroud :

asegúrese de que todo funcione bajo utf-8 (o cualquier conjunto de caracteres preferible). luego agregue la línea skip-character-set-client-handshake a my.cnf .

esto funciona para mí hasta ahora. Experimenté con algunos caracteres utf-8 de doble ancho. Tanto la insert como la select correctamente y se muestran correctamente en el navegador.

lo que significa saltarse el apretón de manos aún no está claro. y el servidor mysql ahora ya no puede utilizar ningún juego de caracteres, excepto utf-8, lo que hace que esta solución no sea práctica ya que simplemente no puedo aplicar esta configuración a todos los servidores en los que se ejecuta mi sitio web.

así que no estoy adoptando esta solución. Más comentarios y respuestas son muy apreciados.


De acuerdo a las siguientes publicaciones de MySQL.

http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html http://dev.mysql.com/doc/refman/5.0/en/charset-applications.html

su configuración no es completamente correcta, es decir

utilizar

[mysqld] character-set-server=utf8 collation-server=utf8_general_ci

en lugar de

[mysqld] default-character-set=utf8

para el cliente que solo encontré

[mysql] default-character-set=utf8

no

[client] default-character-set=utf8

Intenta y dame algunos comentarios.

Puedo recordar que una vez leí sobre una configuración var para desactivar la posibilidad de que un cliente cambie la configuración de caracteres. Pero no puedo encontrar el ref en la documentación de mysql ahora. Si lo encuentro te lo hago saber.

Espero que ayude.

Saludos

ACTUALIZAR

@Unisland BTW Encontré este hilo http://www.webmasterworld.com/php/3553642.htm donde se discute un problema similar

Prueba cualquiera

Así que puedes intentar agregar un:
[mysqld]
init-connect = ''SET NAMES utf8''

o

[cliente]
conjunto de caracteres predeterminado = utf8

[mysqld]
conjunto de caracteres-servidor = utf8
conjunto de caracteres predeterminado = utf8
default-collation = utf8_unicode_ci
conjunto de caracteres-cliente = utf8

para configurar esto como predeterminado para todas las conexiones, o comience con estas consultas después de que su script específico se conecte a la base de datos antes de enviar otras consultas: SET NAMES utf8; SET CHARACTER_SET utf8;


Ha diagnosticado correctamente el problema básico: si bien puede cambiar el conjunto de caracteres del cliente MySQL predeterminado en la máquina cliente my.cnf o .my.cnf , PHP no usa estos archivos.

Si piensa en cómo funcionan las extensiones MySQLi / MySQL de PHP, esto tendrá sentido: no tienen nada que ver con el programa cliente mysql y no rastrearán su sistema de archivos en busca de archivos de configuración, ya que usan libmysql directamente.

Para cambiar el conjunto de caracteres predeterminado real de libmysql, solo tendrá que reconstruir libmysql. Puede que esa no sea una respuesta que te guste (ya que estás usando archivos binarios de MySQL precompilados), pero es la respuesta real. Los valores predeterminados se establecen en el momento de la compilación, y luego se pueden anular en el tiempo de ejecución.

Si no quieres hacer esto y llamar a set_charset () te molesta, mi sugerencia sería simplemente extender la clase MySQLi y usar esa clase en lugar de mysqli. es decir:

class MyDB extends mysqli { // (You could set defaults for the params here if you want // i.e. $host = ''myserver'', $dbname = ''myappsdb'' etc.) public function __construct($host = NULL, $username = NULL, $dbname = NULL, $port = NULL, $socket = NULL) { parent::__construct($host, $username, $dbname, $port, $socket); $this->set_charset("utf8"); } }

Por lo general, en una aplicación, de todos modos, tendrá algún tipo de capa de abstracción de la base de datos, así que puede hacer que esta capa use MyDB en lugar de mysqli, o puede hacer que esta capa sea MyDB y agregar o anular cualquier método que desee (lo he hecho esto con aplicaciones simples sin ORM).

Es una buena práctica tener siempre algún tipo de capa de abstracción de base de datos, incluso si comienza como solo la class MyDB extends mysqli {} porque nunca tendrá que buscar / reemplazar todo el código base para hacer pequeños cambios.

RE: su solución, como explica, esto esencialmente codifica su servidor de bases de datos completo a UTF-8 independientemente de lo que soliciten los clientes. En lugar de tener varias bases de datos, cada una con su propio conjunto de caracteres, el servidor solo funciona con UTF-8 y puede manipular los datos de forma silenciosa si los clientes se conectan con otro conjunto de caracteres. Esto es fundamentalmente incorrecto porque efectivamente ha movido un aspecto de la configuración de su aplicación (conjunto de datos de la base de datos) desde la máquina de la aplicación / cliente al servidor de la base de datos donde realmente no pertenece.

Si piensas en las capas de la pila de aplicaciones,

[server] <=> [network] <=> [client libmysql] <=> [PHP binary] <=> [app]

entonces comprenderá que el lugar "correcto" para una configuración específica de la aplicación como esta se encuentra en la propia aplicación, no en otra parte de la pila. Puede que no le guste tener que especificar el conjunto de caracteres de su base de datos en PHP, pero si lo piensa, realmente es a donde pertenece, porque también es donde está especificando la base de datos a la que desea conectarse: es un parámetro de conexión. no es un problema de configuración del servidor. Codificar el conjunto de caracteres en cualquier otro lugar hace que su aplicación no sea portátil.