आपने मूल समस्या का सही निदान किया है:जबकि आप क्लाइंट मशीन के my.cnf
में डिफ़ॉल्ट MySQL क्लाइंट वर्णसेट को बदल सकते हैं या .my.cnf
, इन फ़ाइलों का उपयोग PHP द्वारा नहीं किया जाता है।
यदि आप सोचते हैं कि PHP के MySQLi/MySQL एक्सटेंशन कैसे काम करते हैं, तो यह समझ में आता है -- उनका 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");
}
}
आम तौर पर किसी एप्लिकेशन में आपके पास किसी प्रकार की डेटाबेस एब्स्ट्रैक्शन परत होगी, इसलिए आप या तो इस परत को mysqli के बजाय MyDB का उपयोग कर सकते हैं, या आपके पास यह परत हो सकती है be MyDB और जो भी तरीके आप चाहते हैं उन्हें जोड़ें या ओवरराइड करें (मैंने इसे सरल ओआरएम-कम ऐप्स के साथ किया है)।
किसी प्रकार की डेटाबेस एब्स्ट्रैक्शन परत को हमेशा रखना एक अच्छा अभ्यास है, भले ही यह केवल class MyDB extends mysqli {}
के रूप में शुरू होता है क्योंकि तब आपको छोटे-छोटे परिवर्तन करने के लिए कभी भी अपना संपूर्ण कोड आधार खोजने/बदलने की आवश्यकता नहीं होगी।
आरई:आपका वर्कअराउंड, जैसा कि आप समझाते हैं, यह अनिवार्य रूप से आपके संपूर्ण डीबी सर्वर को यूटीएफ -8 में हार्डकोड करता है, भले ही क्लाइंट के अनुरोध पर ध्यान दिए बिना। एकाधिक डेटाबेस होने के बजाय, प्रत्येक अपने स्वयं के वर्णमाला के साथ, सर्वर केवल यूटीएफ -8 के साथ काम करता है और यदि क्लाइंट किसी अन्य वर्णसेट से जुड़ता है तो चुपचाप डेटा को मैनेज कर सकता है। यह मौलिक रूप से गलत है क्योंकि आपने अपने एप्लिकेशन के कॉन्फ़िगरेशन (डेटाबेस वर्णसेट) के एक पहलू को ऐप/क्लाइंट मशीन से डेटाबेस सर्वर पर प्रभावी ढंग से स्थानांतरित कर दिया है, जहां यह वास्तव में संबंधित नहीं है।
यदि आप एप्लिकेशन स्टैक की परतों के बारे में सोचते हैं,
[server] <=> [network] <=> [client libmysql] <=> [PHP binary] <=> [app]
तो आप समझेंगे कि इस तरह के ऐप-विशिष्ट कॉन्फ़िगरेशन के लिए "सही" स्थान ऐप में ही है, स्टैक में कहीं और नहीं। हो सकता है कि आप PHP में अपने डेटाबेस के चारसेट को निर्दिष्ट करना पसंद न करें, लेकिन यदि आप इसके बारे में सोचते हैं, तो यह वास्तव में वह जगह है जहाँ से यह संबंधित है, क्योंकि यह वह जगह भी है जहाँ आप उस डेटाबेस को निर्दिष्ट कर रहे हैं जिसे आप कनेक्ट करना चाहते हैं - यह एक कनेक्शन पैरामीटर है, सर्वर कॉन्फ़िगरेशन समस्या नहीं है। चारसेट को कहीं और हार्डकोड करना आपके एप्लिकेशन को गैर-पोर्टेबल बना देता है।