sql >> Base de Datos >  >> RDS >> Mysql

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

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

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

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

Si no quiere hacer esto y llamar a set_charset() le 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 tendrá algún tipo de capa de abstracción de base de datos de todos modos, por lo que puede hacer que esta capa use MyDB en lugar de mysqli, o puede hacer que esta capa sea MyDB y agregue o anule los métodos que desee (he hecho esto con aplicaciones simples sin ORM).

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

RE:su solución alternativa, como explica, esto esencialmente codifica todo su servidor de base de datos en 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 alterar los datos de forma silenciosa si los clientes se conectan con otro conjunto de caracteres. Esto es fundamentalmente incorrecto porque efectivamente movió un aspecto de la configuración de su aplicación (juego de caracteres de la base de datos) de la máquina de la aplicación/cliente al servidor de la base de datos donde realmente no pertenece.

Si piensa 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 es la propia aplicación, no en otra parte de la pila. Es posible que no le guste tener que especificar el conjunto de caracteres de su base de datos en PHP, pero si lo piensa, ahí es realmente 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.