Mysql
 sql >> Base de données >  >> RDS >> Mysql

une façon permanente de faire mysqli->set_charset() ?

Vous avez correctement diagnostiqué le problème de base :bien que vous puissiez modifier le jeu de caractères par défaut du client MySQL dans le fichier my.cnf de la machine cliente ou .my.cnf , ces fichiers ne sont pas utilisés par PHP.

Si vous réfléchissez au fonctionnement des extensions MySQLi/MySQL de PHP, cela aura du sens -- elles n'ont rien à voir avec mysql programme client et ne vont pas explorer votre système de fichiers pour les fichiers de configuration, car ils utilisent libmysql directement.

Pour changer le jeu de caractères par défaut de libmysql, il vous suffit de reconstruire libmysql. Ce n'est peut-être pas une réponse que vous aimez (puisque vous utilisez des binaires MySQL précompilés), mais c'est la vraie réponse. Les valeurs par défaut sont définies au moment de la compilation, puis peuvent être remplacées lors de l'exécution.

Si vous ne voulez pas faire cela et que l'appel à set_charset() vous ennuie, ma suggestion serait simplement d'étendre la classe MySQLi et d'utiliser cette classe à la place de mysqli. c'est-à-dire :

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

Généralement, dans une application, vous aurez de toute façon une sorte de couche d'abstraction de base de données, vous pouvez donc soit faire en sorte que cette couche utilise MyDB au lieu de mysqli, soit que cette couche soit be MyDB et ajoutez ou remplacez les méthodes de votre choix (je l'ai fait avec de simples applications sans ORM).

C'est une bonne pratique de toujours avoir une sorte de couche d'abstraction de base de données, même si elle commence comme juste class MyDB extends mysqli {} car alors vous n'aurez jamais à rechercher/remplacer toute votre base de code pour apporter de petites modifications.

RE:votre solution de contournement, comme vous l'expliquez, cela code essentiellement en dur l'intégralité de votre serveur de base de données en UTF-8, quelle que soit la demande des clients. Au lieu d'avoir plusieurs bases de données, chacune avec son propre jeu de caractères, le serveur ne fonctionne qu'avec UTF-8 et peut mutiler silencieusement les données si les clients se connectent avec un autre jeu de caractères. C'est fondamentalement faux car vous avez effectivement déplacé un aspect de la configuration de votre application (jeu de caractères de base de données) de l'application/machine cliente vers le serveur de base de données auquel il n'appartient pas vraiment.

Si vous pensez aux couches de la pile d'applications,

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

alors vous comprendrez que l'emplacement "correct" pour une configuration spécifique à une application comme celle-ci se trouve dans l'application elle-même, et non ailleurs dans la pile. Vous n'aimez peut-être pas avoir à spécifier le jeu de caractères de votre base de données en PHP, mais si vous y réfléchissez, c'est vraiment là qu'il appartient, car c'est aussi là que vous spécifiez la base de données elle-même à laquelle vous voulez vous connecter -- c'est un paramètre de connexion, pas un problème de configuration du serveur. Le codage en dur du jeu de caractères n'importe où ailleurs rend votre application non portable.