एक PHP स्ट्रिंग केवल बाइट्स का एक क्रम है, जिसमें कोई एन्कोडिंग नहीं है जो भी इसे टैग किया गया है। स्ट्रिंग मान विभिन्न स्रोतों से आ सकते हैं: क्लाइंट (HTTP पर), एक डेटाबेस, एक फ़ाइल, या आपके स्रोत कोड में स्ट्रिंग शाब्दिक से। PHP इन सभी को बाइट अनुक्रम के रूप में पढ़ता है, और यह कभी भी किसी भी एन्कोडिंग जानकारी को नहीं निकालता है।
जब तक आपके सभी डेटा स्रोत और गंतव्य समान एन्कोडिंग का उपयोग करते हैं, तब तक सबसे खराब बात यह हो सकती है कि स्ट्रिंग स्थिति गलत हैं (यदि आप मल्टी-बाइट एन्कोडिंग का उपयोग करते हैं), क्योंकि PHP बाइट्स की गणना करेगा, वर्ण नहीं।
लेकिन अगर एन्कोडिंग मेल नहीं खाते (जैसे आप UTF-8 के रूप में संग्रहीत स्रोत फ़ाइल में एक स्ट्रिंग शाब्दिक लिखते हैं, और फिर इसे एक डेटाबेस में भेजें जो लैटिन -1 की अपेक्षा करता है), तो PHP आपके लिए कोई रूपांतरण नहीं करेगा: यह होगा खुशी से बाइट्स को कच्चे पर कॉपी करें।
सबसे बड़ा समाधान यह है:
- UTF-8 में PHP की आंतरिक एन्कोडिंग सेट करें।
- अपने सभी स्रोत फ़ाइलों को UTF-8 के रूप में सहेजें।
- अपने आउटपुट एन्कोडिंग के रूप में UTF-8 का उपयोग करें (उपयुक्त
Content-type
हेडर भेजने के लिए मत भूलना )।
- UTF-8 (
SET NAMES UTF8
MySQL में) का उपयोग करने के लिए डेटाबेस कनेक्शन सेट करें ।
- यदि संभव हो तो बाकी सब को UTF-8 में कॉन्फ़िगर करें।
- ऐसी किसी भी चीज़ के लिए जिसे आप नियंत्रित नहीं कर सकते हैं (उदाहरण के लिए तृतीय-पक्ष वेब सेवाएँ), सुनिश्चित करें कि आप एन्कोडिंग को जानते हैं, और UTF-8 को जितनी जल्दी हो सके, और जितना संभव हो सके दूसरे एन्कोडिंग में वापस करें।
UTF-8 क्यों? क्योंकि यह सभी यूनिकोड वर्णों का प्रतिनिधित्व कर सकता है और इस प्रकार सभी मौजूदा 7-बिट और 8-बिट एन्कोडिंग्स को अलग कर देता है, और क्योंकि यह ASCII के साथ द्विआधारी संगत है, अर्थात, प्रत्येक वैध ASCII स्ट्रिंग एक मान्य UTF-8 स्ट्रिंग (vv नहीं है) ।)।
आपके उदाहरण में, यह क्या होता है।
सबसे पहले, आप अपनी स्रोत फ़ाइल सहेजते हैं; आपका टेक्स्ट संपादक शायद UTF-8 का उपयोग करने के लिए कॉन्फ़िगर किया गया है, इसलिए आपका स्ट्रिंग शाब्दिक डिस्क पर UTF-8 एन्कोडेड है। PHP इस फाइल को पढ़ता है, स्ट्रिंग को बाइट्स की एक श्रृंखला के रूप में व्याख्या करता है; $original
अब 7 वर्णों का एक UTF-8 एन्कोडेड स्ट्रिंग रखता है, जो सिर्फ एक बाइट अनुक्रम है (हालांकि इसमें 7 से अधिक बाइट्स हैं, क्योंकि प्रत्येक वर्ण दो या अधिक बाइट्स द्वारा दर्शाया गया है)। यदि आप कॉल करते हैं echo $original
, तो एन्कोडेड स्ट्रिंग को क्लाइंट के पास भेजा जाता है; यदि आपने क्लाइंट को UTF-8 की अपेक्षा की है, तो सब कुछ ठीक है, लेकिन यदि आपने नहीं किया है, तो PHP में अंतर बताने का कोई तरीका नहीं है, और आप ब्राउज़र में कचरा खत्म कर देंगे। प्रयोग के तौर पर, यह आज़माएँ:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
एन्कोडिंग-अज्ञेयवादी है और एक निश्चित-चौड़ाई 8 बिट एन्कोडिंग मानता है, अर्थात, प्रति वर्ण एक बाइट, इसलिए यह बाइट्स की गणना करेगा, वर्ण नहीं।