PHP आंतरिक रूप से तारों का प्रतिनिधित्व कैसे करती है?


18

UTF8?
UTF16?

क्या PHP में तार इस्तेमाल किए गए एन्कोडिंग का भी ध्यान रखते हैं?

आइए इस स्क्रिप्ट को उदाहरण के लिए देखें। कहो मैं चला:

$original = "शक्नोम्यत्तुम्";

वास्तव में क्या होता है?

जाहिर है मुझे लगता है कि $originalइसमें सिर्फ 7 अक्षर नहीं होंगे। उन ग्लिफ़ को प्रत्येक को कई बाइट्स द्वारा प्रस्तुत किया जाना चाहिए।

फिर मैं करता हूं:

$converted = mb_convert_encoding ($original , "UTF-8");

इससे क्या होगा $converted? कैसे $convertedअलग होगा $original?

यह सिर्फ एक ही बाइट अनुक्रम के रूप में होगा, $originalलेकिन एक अलग एन्कोडिंग के साथ?


1
PHP का कौन सा संस्करण? PHP <6 देशी UTF-8 को नहीं संभाल सकता। इस समस्या को हल / हल करने के लिए पैकेज और विधियाँ हैं। Utf-8 और php के साथ Google मज़ा। फिर PHP के बजाय दूसरे प्लेटफार्म पर जाएँ। :)
एंड्रयू टी फिनेल

4
PHP <6? जारी किए गए PHP के हर संस्करण में यह शामिल होगा ...
tadmers

1
इसके अलावा, PHP UTF-8 को संभाल सकता है , इसके पास केवल एक समर्पित डेटा प्रकार नहीं है, इसलिए आपको यह देखना होगा कि आप क्या कर रहे हैं।
तदमर्स

जवाबों:


22

एक PHP स्ट्रिंग केवल बाइट्स का एक क्रम है, जिसमें कोई एन्कोडिंग नहीं है जो भी इसे टैग किया गया है। स्ट्रिंग मान विभिन्न स्रोतों से आ सकते हैं: क्लाइंट (HTTP पर), एक डेटाबेस, एक फ़ाइल, या आपके स्रोत कोड में स्ट्रिंग शाब्दिक से। PHP इन सभी को बाइट अनुक्रम के रूप में पढ़ता है, और यह कभी भी किसी भी एन्कोडिंग जानकारी को नहीं निकालता है।

जब तक आपके सभी डेटा स्रोत और गंतव्य समान एन्कोडिंग का उपयोग करते हैं, तब तक सबसे खराब बात यह हो सकती है कि स्ट्रिंग स्थिति गलत हैं (यदि आप मल्टी-बाइट एन्कोडिंग का उपयोग करते हैं), क्योंकि PHP बाइट्स की गणना करेगा, वर्ण नहीं।

लेकिन अगर एन्कोडिंग मेल नहीं खाते (जैसे आप UTF-8 के रूप में संग्रहीत स्रोत फ़ाइल में एक स्ट्रिंग शाब्दिक लिखते हैं, और फिर इसे एक डेटाबेस में भेजें जो लैटिन -1 की अपेक्षा करता है), तो PHP आपके लिए कोई रूपांतरण नहीं करेगा: यह होगा खुशी से बाइट्स को कच्चे पर कॉपी करें।

सबसे बड़ा समाधान यह है:

  • UTF-8 में PHP की आंतरिक एन्कोडिंग सेट करें।
  • अपने सभी स्रोत फ़ाइलों को UTF-8 के रूप में सहेजें।
  • अपने आउटपुट एन्कोडिंग के रूप में UTF-8 का उपयोग करें (उपयुक्त Content-typeहेडर भेजने के लिए मत भूलना )।
  • UTF-8 ( SET NAMES UTF8MySQL में) का उपयोग करने के लिए डेटाबेस कनेक्शन सेट करें ।
  • यदि संभव हो तो बाकी सब को 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 बिट एन्कोडिंग मानता है, अर्थात, प्रति वर्ण एक बाइट, इसलिए यह बाइट्स की गणना करेगा, वर्ण नहीं।


तो $ परिवर्तित उसी स्ट्रिंग का प्रतिनिधित्व करेगा लेकिन अन्य एन्कोडिंग में। वास्तविक कच्चे एन्कोडिंग, जो कि पीएचपी स्टोर है, अलग-अलग होगा।
user4951

2
मैं इसे आपके लिए दोहराऊंगा: PHP स्टोर बाइट्स, अक्षर नहीं, और यह सभी एन्कोडिंग के बारे में नहीं जानता है (हालांकि कुछ लाइब्रेरी फ़ंक्शंस करते हैं।
tdamers

1
ओह, और यह "पीएचपी" है, न कि "पीएचपी"।
tdammers

2
अगर कच्चे बाइट्स वही हैं जो $ मूल और $ परिवर्तित के बीच अंतर है। यह वही है जो मैं पूछ रहा हूं।
user4951

2
ओह, ठीक है, यही आपका मतलब है। हां, एन्कोडिंग रूपांतरण के अनुसार कच्ची बाइट्स बदल जाती हैं। PHP को एन्कोडिंग याद नहीं है, लेकिन यदि आप एक स्ट्रिंग को utf-8 से लैटिन -1 में परिवर्तित करते हैं, और फिर परिणाम को utf-8 के रूप में मानते हैं, तो आपको अजीब परिणाम दिखाई देंगे।
tdammers
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.