Mysql
 sql >> Datenbank >  >> RDS >> Mysql

eine dauerhafte Möglichkeit, mysqli->set_charset() zu tun?

Sie haben das grundlegende Problem richtig diagnostiziert:Sie können zwar den standardmäßigen MySQL-Client-Zeichensatz in der my.cnf des Client-Rechners ändern oder .my.cnf , diese Dateien werden von PHP nicht verwendet.

Wenn Sie darüber nachdenken, wie die MySQLi/MySQL-Erweiterungen von PHP funktionieren, wird dies Sinn machen – sie haben nichts mit mysql zu tun Client-Programm und werden Ihr Dateisystem nicht nach Konfigurationsdateien durchsuchen, da sie libmysql verwenden direkt.

Um den tatsächlichen Standardzeichensatz von libmysql zu ändern, müssen Sie lediglich libmysql neu erstellen. Das ist vielleicht keine Antwort, die Ihnen gefällt (da Sie vorkompilierte MySQL-Binärdateien verwenden), aber es ist die eigentliche Antwort. Die Standardwerte werden zur Kompilierzeit gesetzt und können dann zur Laufzeit überschrieben werden.

Wenn Sie dies nicht möchten und der Aufruf von set_charset() Sie nervt, wäre mein Vorschlag, einfach die MySQLi-Klasse zu erweitern und diese Klasse anstelle von mysqli zu verwenden. d.h.:

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

Normalerweise haben Sie in einer Anwendung sowieso eine Art Datenbank-Abstraktionsschicht, also können Sie diese Schicht entweder MyDB anstelle von mysqli verwenden lassen, oder Sie können diese Schicht sein MyDB und fügen Sie beliebige Methoden hinzu oder überschreiben Sie sie (ich habe dies mit einfachen ORM-losen Apps gemacht).

Es ist eine gute Praxis, immer eine Art Datenbank-Abstraktionsschicht zu haben, auch wenn es damit beginnt, dass class MyDB extends mysqli {} weil Sie dann nie Ihre gesamte Codebasis durchsuchen/ersetzen müssen, um kleine Änderungen vorzunehmen.

RE:Ihre Problemumgehung, wie Sie erklären, codiert im Wesentlichen Ihren gesamten Datenbankserver auf UTF-8, unabhängig davon, was Clients anfordern. Anstatt mehrere Datenbanken mit jeweils eigenem Zeichensatz zu haben, arbeitet der Server nur mit UTF-8 und kann Daten stillschweigend verfälschen, wenn sich Clients mit einem anderen Zeichensatz verbinden. Dies ist grundlegend falsch, da Sie einen Aspekt der Konfiguration Ihrer Anwendung (Datenbankzeichensatz) effektiv von der App/dem Client-Rechner auf den Datenbankserver verschoben haben, wo er eigentlich nicht hingehört.

Wenn Sie an die Schichten des Anwendungsstapels denken,

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

Dann werden Sie verstehen, dass der „richtige“ Ort für eine App-spezifische Konfiguration wie diese in der App selbst ist, nicht an anderer Stelle im Stack. Sie mögen es vielleicht nicht, den Zeichensatz Ihrer Datenbank in PHP angeben zu müssen, aber wenn Sie darüber nachdenken, gehört er wirklich dorthin, denn hier geben Sie auch die Datenbank selbst an, mit der Sie sich verbinden möchten - es ist ein Verbindungsparameter, kein Serverkonfigurationsproblem. Wenn Sie den Zeichensatz irgendwo anders fest codieren, wird Ihre Anwendung nicht portierbar.