sql >> Databasteknik >  >> RDS >> Mysql

ett permanent sätt att göra mysqli->set_charset()?

Du har diagnostiserat det grundläggande problemet korrekt:Även om du kan ändra standard MySQL-klientens teckenuppsättning i klientdatorns my.cnf eller .my.cnf , dessa filer används inte av PHP.

Om du tänker på hur PHPs MySQLi/MySQL-tillägg fungerar, kommer detta att vara vettigt -- de har ingenting att göra med mysql klientprogram och kommer inte att genomsöka ditt filsystem efter konfigurationsfiler, eftersom de använder libmysql direkt.

För att ändra libmysqls faktiska standardteckenuppsättning behöver du bara bygga om libmysql. Det kanske inte är ett svar du gillar (eftersom du använder förkompilerade MySQL-binärer), men det är det faktiska svaret. Standardinställningarna ställs in vid kompilering och kan sedan åsidosättas under körning.

Om du inte vill göra detta och anropet set_charset() irriterar dig, skulle mitt förslag vara att helt enkelt utöka klassen MySQLi och använda den klassen i stället för mysqli. dvs:

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

Vanligtvis i en applikation kommer du att ha något slags databasabstraktionslager ändå, så du kan antingen låta det här lagret använda MyDB istället för mysqli, eller så kan du ha det här lagret vara MyDB och lägg till eller åsidosätt alla metoder du vill ha (jag har gjort detta med enkla appar utan ORM).

Det är en bra praxis att alltid ha någon form av databasabstraktionslager, även om det börjar som bara class MyDB extends mysqli {} för då behöver du aldrig söka/byta ut hela din kodbas för att göra små ändringar.

RE:din lösning, som du förklarar, hårdkodar detta i huvudsak hela din db-server till UTF-8 oavsett vad klienter begär. Istället för att ha flera databaser, var och en med sin egen teckenuppsättning, fungerar servern bara med UTF-8 och kan tyst mangle data om klienter ansluter till en annan teckenuppsättning. Detta är i grunden fel eftersom du faktiskt har flyttat en aspekt av din applikations konfiguration (databasteckenuppsättning) från app-/klientdatorn till databasservern där den egentligen inte hör hemma.

Om du tänker på applikationsstackens lager,

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

då kommer du att förstå att den "rätta" platsen för en appspecifik konfiguration som denna är i själva appen, inte någon annanstans i stacken. Du kanske inte gillar att behöva ange din databas teckenuppsättning i PHP, men om du tänker efter så är det verkligen där den hör hemma, eftersom det också är där du anger själva databasen som du vill ansluta till -- det är en anslutningsparameter, inte ett serverkonfigurationsproblem. Att hårdkoda teckenuppsättningen någon annanstans gör din applikation icke-portabel.



  1. MYSQL:hur man omordnar ett bord

  2. Vilka är för- och nackdelarna med att utföra beräkningar i sql vs. i din ansökan

  3. Räkna antalet distinkta rader för flera värden

  4. Distribuera MySQL, MariaDB, Percona Server, MongoDB eller PostgreSQL - enkelt med ClusterControl