U hebt het basisprobleem correct gediagnosticeerd:terwijl u de standaard MySQL-clienttekenset kunt wijzigen in my.cnf
van de clientcomputer of .my.cnf
, deze bestanden worden niet gebruikt door PHP.
Als je nadenkt over hoe PHP's MySQLi/MySQL-extensies werken, is dit logisch -- ze hebben niets te maken met de mysql
client-programma en gaan uw bestandssysteem niet crawlen voor configuratiebestanden, omdat ze libmysql
gebruiken rechtstreeks.
Om de werkelijke standaardtekenset van libmysql te wijzigen, hoeft u alleen maar libmysql opnieuw op te bouwen. Dat is misschien geen antwoord dat je leuk vindt (omdat je voorgecompileerde MySQL-binaries gebruikt), maar het is het daadwerkelijke antwoord. De standaardinstellingen worden tijdens het compileren ingesteld en kunnen tijdens runtime worden overschreven.
Als je dit niet wilt doen en het aanroepen van set_charset() je ergert, zou mijn suggestie zijn om gewoon de MySQLi-klasse uit te breiden en die klasse te gebruiken in plaats van mysqli. d.w.z.:
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");
}
}
Meestal heb je in een applicatie sowieso een soort database-abstractielaag, dus je kunt deze laag MyDB laten gebruiken in plaats van mysqli, of je kunt deze laag laten zijn MyDB en voeg alle gewenste methoden toe of overschrijf ze (ik heb dit gedaan met eenvoudige ORM-loze apps).
Het is een goede gewoonte om altijd een soort database-abstractielaag te hebben, zelfs als deze begint als slechts class MyDB extends mysqli {}
uit omdat je dan nooit je hele codebase hoeft te doorzoeken/vervangen om kleine wijzigingen aan te brengen.
RE:uw tijdelijke oplossing, zoals u uitlegt, deze codeert in wezen uw hele db-server naar UTF-8, ongeacht wat klanten vragen. In plaats van meerdere databases te hebben, elk met zijn eigen tekenset, werkt de server alleen met UTF-8 en kan deze gegevens in stilte manipuleren als clients verbinding maken met een andere tekenset. Dit is fundamenteel verkeerd omdat u in feite één aspect van de configuratie van uw toepassing (database-tekenset) van de app/client-machine naar de databaseserver heeft verplaatst waar het niet echt thuishoort.
Als je nadenkt over de lagen van de applicatie-stack,
[server] <=> [network] <=> [client libmysql] <=> [PHP binary] <=> [app]
dan zul je begrijpen dat de "juiste" plaats voor een app-specifieke configuratie als deze in de app zelf is, niet ergens anders in de stapel. Misschien vind je het niet leuk om de karakterset van je database in PHP te specificeren, maar als je erover nadenkt, is dat echt waar het thuishoort, want het is ook waar je de database zelf specificeert waarmee je verbinding wilt maken -- het is een verbindingsparameter, geen probleem met de serverconfiguratie. Door de karakterset ergens anders hard te coderen, is uw toepassing niet-draagbaar.