Mysql
 sql >> Database >  >> RDS >> Mysql

un modo permanente di fare mysqli->set_charset()?

Hai diagnosticato correttamente il problema di base:mentre puoi modificare il set di caratteri predefinito del client MySQL nel my.cnf della macchina client o .my.cnf , questi file non vengono utilizzati da PHP.

Se pensi a come funzionano le estensioni MySQLi/MySQL di PHP, questo avrà senso:non hanno nulla a che fare con mysql programma client e non eseguiranno la scansione del tuo filesystem per i file di configurazione, perché usano libmysql direttamente.

Per modificare il set di caratteri predefinito effettivo di libmysql, dovrai solo ricostruire libmysql. Potrebbe non essere una risposta che ti piace (dal momento che stai utilizzando binari MySQL precompilati), ma è la risposta effettiva. Le impostazioni predefinite vengono impostate in fase di compilazione e quindi possono essere sovrascritte in fase di esecuzione.

Se non vuoi farlo e chiamare set_charset() ti infastidisce, il mio suggerimento sarebbe semplicemente estendere la classe MySQLi e usare quella classe al posto di mysqli. cioè:

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");
  } 
} 

Tipicamente in un'applicazione avrai comunque una sorta di livello di astrazione del database, quindi puoi fare in modo che questo livello usi MyDB invece di mysqli, oppure puoi avere questo livello essere MyDB e aggiungi o sostituisci qualsiasi metodo desideri (l'ho fatto con semplici app prive di ORM).

È buona norma avere sempre una sorta di livello di astrazione del database, anche se inizia solo come class MyDB extends mysqli {} perché così non dovrai mai cercare/sostituire l'intera codebase per apportare piccole modifiche.

RE:la tua soluzione alternativa, come spieghi, essenzialmente codifica l'intero server db in UTF-8 indipendentemente da ciò che i client richiedono. Invece di avere più database, ciascuno con il proprio set di caratteri, il server funziona solo con UTF-8 e può alterare silenziosamente i dati se i client si connettono con un altro set di caratteri. Questo è fondamentalmente sbagliato perché hai effettivamente spostato un aspetto della configurazione della tua applicazione (set di caratteri del database) dalla macchina dell'app/client al server del database a cui in realtà non appartiene.

Se pensi ai livelli dello stack di applicazioni,

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

quindi capirai che il posto "corretto" per una configurazione specifica dell'app come questa è nell'app stessa, non altrove nello stack. Potrebbe non piacerti dover specificare il set di caratteri del tuo database in PHP, ma se ci pensi, è davvero a questo che appartiene, perché è anche il punto in cui stai specificando il database stesso a cui vuoi connetterti:è un parametro di connessione, non è un problema di configurazione del server. L'hardcoding del set di caratteri altrove rende la tua applicazione non portatile.