Правилно диагностицирахте основния проблем:Докато можете да промените клиентския набор от символи по подразбиране на MySQL в my.cnf
на клиентската машина или .my.cnf
, тези файлове не се използват от PHP.
Ако помислите как работят разширенията MySQLi/MySQL на PHP, това ще има смисъл - те нямат нищо общо с mysql
клиентска програма и няма да обхождат вашата файлова система за конфигурационни файлове, защото използват libmysql
директно.
За да промените действителния набор от символи по подразбиране на libmysql, просто ще трябва да възстановите libmysql. Това може да не е отговорът, който харесвате (тъй като използвате предварително компилирани MySQL двоични файлове), но това е действителният отговор. Настройките по подразбиране се задават по време на компилиране и след това могат да бъдат отменени по време на изпълнение.
Ако не искате да правите това и извикването на set_charset() ви дразни, моето предложение би било просто да разширите класа MySQLi и да използвате този клас вместо mysqli. т.е.:
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");
}
}
Обикновено в едно приложение така или иначе ще имате някакъв вид абстракция на база данни, така че можете или този слой да използва MyDB вместо mysqli, или можете да накарате този слой да да бъде MyDB и добавете или отменете всички методи, които искате (правих това с прости приложения без ORM).
Добра практика е винаги да имате някакъв вид абстракционен слой на базата данни, дори ако той започва като просто class MyDB extends mysqli {}
защото тогава никога няма да се налага да търсите/заменяте цялата си кодова база, за да направите малки промени.
RE:вашето заобиколно решение, както обяснявате, това по същество хардкодира целия ви db сървър към UTF-8, независимо от това какво искат клиентите. Вместо да има множество бази данни, всяка със собствен набор от знаци, сървърът работи само с UTF-8 и може безшумно да променя данните, ако клиентите се свържат с друг набор от знаци. Това е фундаментално погрешно, защото на практика сте преместили един аспект от конфигурацията на приложението си (набор от знаци на база данни) от машината на приложението/клиента към сървъра на базата данни, където всъщност не му е мястото.
Ако мислите за слоевете на стека на приложения,
[server] <=> [network] <=> [client libmysql] <=> [PHP binary] <=> [app]
тогава ще разберете, че "правилното" място за специфична за приложението конфигурация като тази е в самото приложение, а не другаде в стека. Може да не ви харесва да указвате набора от знаци на вашата база данни в PHP, но ако се замислите, това наистина е мястото, където й е мястото, защото също така указвате самата база данни, с която искате да се свържете - това е параметър за връзка, не е проблем с конфигурацията на сървъра. Твърдо кодиране на набора от знаци навсякъде другаде прави приложението ви непреносимо.