php - यूटीएफ-8 के माध्यम से सभी तरह से




mysql linux apache utf-8 (13)

पुराना विषय, मुझे पता है। पीडीओ का उपयोग कर किसी के साथ कोई समस्या मिली और पीडीओ कनेक्शन स्ट्रिंग के लिए इसका उपयोग करना था:

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

जिस साइट से मैंने इसे लिया है, वह इसे Google कैश का उपयोग करके सौभाग्य से प्राप्त करने में सक्षम था।

मैं एक नया सर्वर स्थापित कर रहा हूं, और अपने वेब एप्लिकेशन में पूरी तरह से यूटीएफ -8 का समर्थन करना चाहता हूं। मैंने अतीत में मौजूदा सर्वर पर कोशिश की है और हमेशा आईएसओ -885 9 -1 पर वापस आने के लिए खत्म होने लगते हैं।

मुझे एन्कोडिंग / वर्णमाला सेट करने की ज़रूरत है? मुझे पता है कि मुझे ऐसा करने के लिए अपाचे, माईएसQL और PHP को कॉन्फ़िगर करने की आवश्यकता है - क्या वहां कुछ मानक चेकलिस्ट है जो मैं अनुसरण कर सकता हूं, या शायद समस्या निवारण कहां हो सकता है?

यह एक नए लिनक्स सर्वर के लिए है, MySQL 5, PHP 5 और अपाचे 2 चला रहा है।


PHP में, आपको या तो multibyte फ़ंक्शंस का उपयोग करने की आवश्यकता होगी, या mbstring.func_overload चालू करें। इस तरह स्ट्रेलन जैसी चीजें काम करती हैं यदि आपके पास ऐसे अक्षर हैं जो एक से अधिक बाइट लेते हैं।

आपको अपने प्रतिक्रियाओं के चरित्र सेट की पहचान करने की भी आवश्यकता होगी। आप या तो ऊपर के रूप में AddDefaultCharset का उपयोग कर सकते हैं, या हेडर लौटने वाले PHP कोड लिख सकते हैं। (या आप अपने एचटीएमएल दस्तावेज़ों में एक मेटा टैग जोड़ सकते हैं।)


मैं चाज़मैटिकस के उत्कृष्ट उत्तर में एक चीज़ जोड़ना चाहता हूं:

मेटा टैग को या तो मत भूलें (इस तरह, या इसका HTML4 या एक्सएचटीएमएल संस्करण ):

<meta charset="utf-8">

यह मामूली लगता है, लेकिन आईई 7 ने मुझे इससे पहले समस्याएं दी हैं।

मैं सब ठीक कर रहा था; डेटाबेस, डेटाबेस कनेक्शन और सामग्री-प्रकार HTTP शीर्षलेख सभी यूटीएफ -8 पर सेट किए गए थे, और यह अन्य सभी ब्राउज़रों में ठीक काम करता था, लेकिन इंटरनेट एक्सप्लोरर ने अभी भी "पश्चिमी यूरोपीय" एन्कोडिंग का उपयोग करने पर जोर दिया।

यह पता चला कि पृष्ठ मेटा टैग गायब था। उस समस्या को हल करना।

संपादित करें:

डब्ल्यू 3 सी वास्तव में I18N को समर्पित एक बड़ा बड़ा अनुभाग है । उनके पास इस मुद्दे से संबंधित कई लेख हैं - HTTP, (एक्स) एचटीएमएल और चीजों के सीएसएस पक्ष का वर्णन:

वे HTTP शीर्षलेख और HTML मेटा टैग (या XML के रूप में एक्सएचटीएमएल के मामले में एक्सएमएल घोषणा दोनों) का उपयोग करने की सलाह देते हैं।


शुरुआत से ही अच्छा लक्ष्य है - आपकी साइट की प्रकृति के आधार पर, मुझे गूगलिंग द्वारा इसके बारे में बहुत सारे संसाधन मिल गए हैं - आप निश्चित रूप से इससे निपटने वाले पहले व्यक्ति नहीं हैं।

रहस्यमय PHP6 यह सब सीधे बाहर होना चाहिए, है ना?

आप सर्वर स्तर पर mysql के लिए वैश्विक डिफ़ॉल्ट वर्णसेट के रूप में utf-8 को बहुत अधिक सेट कर सकते हैं और यह अधिक द्विपक्षीय स्तरों के लिए ठीक से डिफ़ॉल्ट रूप से डिफ़ॉल्ट हो जाएगा।


default_charset में default_charset को सेट करने के अलावा, आप किसी भी आउटपुट से पहले, अपने कोड के भीतर से header() का उपयोग करके सही वर्णसेट भेज सकते हैं:

header('Content-Type: text/html; charset=utf-8');

PHP में यूनिकोड के साथ काम करना तब तक आसान होता है जब तक आप महसूस करते हैं कि अधिकांश स्ट्रिंग फ़ंक्शन यूनिकोड के साथ काम नहीं करते हैं, और कुछ तारों को पूरी तरह से जोड़ सकते हैं । PHP "वर्ण" को 1 बाइट लंबा मानता है। कभी-कभी यह ठीक है (उदाहरण के लिए, explode() केवल बाइट अनुक्रम की तलाश करता है और इसे विभाजक के रूप में उपयोग करता है - इसलिए इससे कोई फर्क नहीं पड़ता कि आप कौन से वास्तविक पात्रों को देखते हैं)। लेकिन दूसरी बार, जब फ़ंक्शन वास्तव में वर्णों पर काम करने के लिए डिज़ाइन किया गया है, तो PHP को यह नहीं पता है कि आपके टेक्स्ट में मल्टी-बाइट वर्ण हैं जो यूनिकोड के साथ पाए जाते हैं।

जांच करने के लिए एक अच्छी लाइब्रेरी phputf8 । यह सभी "खराब" कार्यों को फिर से लिखता है ताकि आप सुरक्षित रूप से यूटीएफ 8 तारों पर काम कर सकें। एमबीस्ट्रिंग एक्सटेंशन जैसे एक्सटेंशन हैं जो आपके लिए भी ऐसा करने का प्रयास करते हैं, लेकिन मैं लाइब्रेरी का उपयोग करना पसंद करता हूं क्योंकि यह अधिक पोर्टेबल है (लेकिन मैं बड़े पैमाने पर बाजार के उत्पादों को लिखता हूं, इसलिए यह मेरे लिए महत्वपूर्ण है)। लेकिन प्रदर्शन बढ़ाने के लिए, fputf8 दृश्यों के पीछे mbstring का उपयोग कर सकते हैं।


इन अद्भुत उत्तरों में जो एकमात्र चीज शामिल होगी, वह है कि आप अपनी फाइलों को utf8 एन्कोडिंग में सहेजने पर जोर दें, मैंने देखा है कि ब्राउज़र इस कोड को आपके कोड एन्कोडिंग के रूप में utf8 सेट करने पर स्वीकार करते हैं। कोई भी सभ्य पाठ संपादक आपको यह दिखाएगा, उदाहरण के लिए नोटपैड ++ में फ़ाइल एन्कॉन्डिंग के लिए मेनू विकल्प है, यह आपको वर्तमान एन्कोडिंग दिखाता है और आपको इसे बदलने में सक्षम बनाता है। मेरे सभी PHP फ़ाइलों के लिए मैं बिना बीओएम के utf8 का उपयोग करता हूं।

कुछ समय पहले मैंने किसी से किसी अन्य व्यक्ति द्वारा डिजाइन किए गए php / mysql एप्लिकेशन के लिए utf8 समर्थन जोड़ने के लिए कहा था, मैंने देखा कि सभी फाइलें एएनएसआई में एन्कोड की गई थीं, इसलिए मुझे सभी फ़ाइलों को परिवर्तित करने के लिए आईसीओएनवी का उपयोग करना पड़ा, डेटाबेस टेबल को बदलने के लिए utf8 charset और utf8_general_ci collate, कनेक्शन के बाद डेटाबेस एब्स्ट्रक्शन लेयर में 'सेट नाम utf8' जोड़ें (यदि 5.3.6 या इससे पहले का उपयोग किया जाता है अन्यथा आपको कनेक्शन स्ट्रिंग में charset = utf8 का उपयोग करना होगा) और php multibyte का उपयोग करने के लिए स्ट्रिंग फ़ंक्शंस को बदलें स्ट्रिंग कार्य समकक्ष।


मैंने अभी एक ही मुद्दे से गुजर लिया है और PHP मैनुअल पर एक अच्छा समाधान मिला है।

मैंने अपनी सभी फाइल एन्कोडिंग को यूटीएफ 8 में बदल दिया, फिर मेरे कनेक्शन पर डिफ़ॉल्ट एन्कोडिंग। इसने सभी समस्याओं को हल किया।

if (!$mysqli->set_charset("utf8")) {
    printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
   printf("Current character set: %s\n", $mysqli->character_set_name());
}

set_charset()


शीर्ष जवाब उत्कृष्ट है। यहां एक नियमित डेबियन / php / mysql सेटअप पर मुझे क्या करना है:

// storage
// debian. apparently already utf-8

// retrieval
// the mysql database was stored in utf-8, 
// but apparently php was requesting iso. this worked: 
// ***notice "utf8", without dash, this is a mysql encoding***
mysql_set_charset('utf8');

// delivery
// php.ini did not have a default charset, 
// (it was commented out, shared host) and
// no http encoding was specified in the apache headers.
// this made apache send out a utf-8 header
// (and perhaps made php actually send out utf-8)
// ***notice "utf-8", with dash, this is a php encoding***
ini_set('default_charset','utf-8');

// submission
// this worked in all major browsers once apache
// was sending out the utf-8 header. i didnt add
// the accept-charset attribute.

// processing
// changed a few commands in php, like substr,
// to mb_substr

बस यही था !


सबसे पहले यदि आप <5.3PHP में हैं तो नहीं। आपको निपटने के लिए कई समस्याएं हैं।

मुझे आश्चर्य है कि किसी ने intl लाइब्रेरी का उल्लेख नहीं किया है, जिसकी यूनिकोड , ग्रैफेम्स , स्ट्रिंग ऑपरेशंस , स्थानीयकरण और कई अन्य लोगों के लिए अच्छा समर्थन है, नीचे देखें।

मैं PHPBenelux'14 पर एलिजाबेथ स्मिथ की slides द्वारा PHP में यूनिकोड समर्थन के बारे में कुछ जानकारी उद्धृत करूंगा

INTL

अच्छा:

  • आईसीयू पुस्तकालय के आसपास लपेटो
  • मानकीकृत लोकल, प्रति स्क्रिप्ट लोकेल सेट करें
  • संख्या स्वरूपण
  • मुद्रा स्वरूपण
  • संदेश स्वरूपण (गेटटेक्स्ट को प्रतिस्थापित करता है)
  • कैलेंडर, तिथियां, टाइमज़ोन और समय
  • Transliterator
  • Spoofchecker
  • संसाधन बंडल
  • कन्वर्टर्स
  • आईडीएन समर्थन
  • Graphemes
  • मिलान
  • iterators

खराब:

  • Zend_multibite का समर्थन नहीं करता है
  • HTTP इनपुट आउटपुट रूपांतरण का समर्थन नहीं करता है
  • फ़ंक्शन ओवरलोडिंग का समर्थन नहीं करता है

mb_string

  • Zend_multibyte समर्थन सक्षम करता है
  • पारदर्शी HTTP इन / आउट एन्कोडिंग का समर्थन करता है
  • Strtoupper जैसे funtionallity के लिए कुछ रैपर प्रदान करता है

iconv

  • वर्णमाला रूपांतरण के लिए प्राथमिक
  • आउटपुट बफर हैंडलर
  • माइम एन्कोडिंग कार्यक्षमता
  • रूपांतरण
  • कुछ स्ट्रिंग हेल्पर्स (लेन, सबस्ट्र, स्ट्रॉप्स, स्ट्रॉप्स)
  • धारा फ़िल्टर stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP') फ़िल्टर करें stream_filter_append($fp, 'convert.iconv.ISO-2022-JP/EUC-JP')

डेटाबेस

  • mysql: तालिकाओं और तालिकाओं पर तालमेल और कनेक्शन पर (संयोजन नहीं)। MySQL - msqli या पीडीओ का भी उपयोग न करें
  • postgresql: pg_set_client_encoding
  • sqlite (3): सुनिश्चित करें कि यह यूनिकोड और intl समर्थन के साथ संकलित किया गया था

कुछ अन्य Gotchas

  • आप PHP और विंडोज़ के साथ यूनिकोड फ़ाइल नामों का उपयोग नहीं कर सकते हैं जब तक आप तीसरे भाग का विस्तार नहीं करते।
  • यदि आप exec, proc_open और अन्य कमांड लाइन कॉल का उपयोग कर रहे हैं तो ASCII में सबकुछ भेजें
  • सादा पाठ सादे पाठ नहीं है, फाइलों में एन्कोडिंग है
  • आप आइकन पर फ़िल्टर के साथ फ्लाई पर फ़ाइलों को परिवर्तित कर सकते हैं

अगर चीजें बदलती हैं और इसी तरह की स्थिति में मैं इस जवाब को अपडेट कर दूंगा।


डेटा संग्रहण :

  • अपने डेटाबेस में सभी टेबल और टेक्स्ट कॉलम पर utf8mb4 वर्ण सेट निर्दिष्ट करें। यह MySQL भौतिक रूप से यूटीएफ -8 में मूल रूप से एन्कोड किए गए मानों को संग्रहीत और पुनर्प्राप्त करता है। ध्यान दें कि यदि utf8mb4_* संयोजन निर्दिष्ट है (बिना किसी स्पष्ट वर्ण सेट के) MySQL utf8mb4 एन्कोडिंग का उपयोग करेगा।

  • MySQL (<5.5.3) के पुराने संस्करणों में, दुर्भाग्य से आप केवल utf8 का उपयोग करने के लिए मजबूर हो जाएंगे, जो केवल यूनिकोड वर्णों के उप-समूह का समर्थन करता है। काश मैं मजाक कर रहा था।

डेटा एक्सेस :

  • आपके एप्लिकेशन कोड (जैसे PHP) में, जो भी डीबी एक्सेस विधि आप उपयोग करते हैं, आपको कनेक्शन charset utf8mb4 पर सेट करने की आवश्यकता होगी। इस तरह, MySQL अपने मूल यूटीएफ -8 से कोई रूपांतरण नहीं करता है जब यह आपके एप्लिकेशन को डेटा बंद कर देता है और इसके विपरीत।

  • कुछ ड्राइवर कनेक्शन चरित्र सेट को कॉन्फ़िगर करने के लिए अपना स्वयं का तंत्र प्रदान करते हैं, जो दोनों अपने आंतरिक राज्य को अपडेट करते हैं और कनेक्शन पर उपयोग किए जाने वाले एन्कोडिंग के MySQL को सूचित करते हैं-यह आमतौर पर पसंदीदा दृष्टिकोण होता है। PHP में:

    • यदि आप PHP ≥ 5.3.6 के साथ PDO अबास्ट्रक्शन लेयर का उपयोग कर रहे हैं, तो आप charset में charset निर्दिष्ट कर सकते हैं:

      $dbh = new PDO('mysql:charset=utf8mb4');
      
    • यदि आप mysqli का उपयोग कर रहे हैं, तो आप set_charset() को कॉल कर सकते हैं:

      $mysqli->set_charset('utf8mb4');       // object oriented style
      mysqli_set_charset($link, 'utf8mb4');  // procedural style
      
    • यदि आप सादे mysql साथ फंस गए हैं लेकिन PHP ≥ 5.2.3 चल रहे हैं, तो आप mysql_set_charset को कॉल कर सकते हैं।

  • यदि ड्राइवर कनेक्शन वर्ण सेट को सेट करने के लिए अपनी तंत्र प्रदान नहीं करता है, तो आपको MySQL को यह बताने के लिए एक प्रश्न जारी करना पड़ सकता है कि आपका एप्लिकेशन कनेक्शन पर डेटा को एन्कोड किए जाने के तरीके से कैसे अपेक्षा करता है: SET NAMES 'utf8mb4'

  • utf8mb4 / utf8 बारे में एक ही विचार उपरोक्त के रूप में लागू होता है।

आउटपुट :

  • यदि आपका एप्लिकेशन अन्य सिस्टम में पाठ प्रसारित करता है, तो उन्हें चरित्र एन्कोडिंग के बारे में सूचित करने की भी आवश्यकता होगी। वेब अनुप्रयोगों के साथ, ब्राउज़र को एन्कोडिंग के बारे में सूचित किया जाना चाहिए जिसमें डेटा भेजा जाता है (HTTP प्रतिक्रिया शीर्षलेख या HTML मेटाडेटा के माध्यम से)।

  • PHP में, आप default_charset php.ini विकल्प का उपयोग कर सकते हैं, या मैन्युअल रूप से Content-Type MIME शीर्षलेख जारी कर सकते हैं, जो कि अधिक काम है लेकिन इसका एक ही प्रभाव है।

इनपुट :

  • दुर्भाग्यवश, आपको इसे संग्रहीत करने या इसे कहीं भी उपयोग करने से पहले प्रत्येक प्राप्त स्ट्रिंग को मान्य यूटीएफ -8 के रूप में सत्यापित करना चाहिए। PHP का mb_check_encoding() चाल करता है, लेकिन आपको इसे धार्मिक रूप से उपयोग करना होगा। इसके आसपास वास्तव में कोई रास्ता नहीं है, क्योंकि दुर्भावनापूर्ण ग्राहक जो भी एन्कोडिंग चाहते हैं, उन्हें डेटा सबमिट कर सकते हैं, और मुझे आपके लिए विश्वसनीय रूप से ऐसा करने के लिए PHP प्राप्त करने के लिए कोई चाल नहीं मिली है।

  • वर्तमान एचटीएमएल स्पेक के पढ़ने से, निम्नलिखित उप-बुलेट आवश्यक नहीं हैं या यहां तक ​​कि आधुनिक HTML के लिए मान्य भी हैं। मेरी समझ यह है कि ब्राउज़र दस्तावेज़ के लिए निर्दिष्ट वर्ण सेट में डेटा के साथ काम करेगा और सबमिट करेगा। हालांकि, यदि आप HTML (XHTML, HTML4, आदि) के पुराने संस्करणों को लक्षित कर रहे हैं, तो ये बिंदु अभी भी उपयोगी हो सकते हैं:

    • केवल एचटीएमएल 5 से पहले एचटीएमएल के लिए : आप यूटीएफ -8 में ब्राउज़र के लिए भेजे गए सभी डेटा चाहते हैं। दुर्भाग्यवश, यदि आप विश्वसनीय रूप से ऐसा करने का एकमात्र तरीका करते हैं तो यह आपके सभी <form> टैग: <form ... accept-charset="UTF-8"> में accept-charset विशेषता जोड़ें।
    • केवल एचटीएमएल 5 से पहले एचटीएमएल के लिए : ध्यान दें कि डब्ल्यू 3 सी एचटीएमएल स्पेक का कहना है कि क्लाइंट सर्वर पर जो भी चार्टसेट सेवा करता है, सर्वर पर फॉर्म भेजने के लिए "डिफ़ॉल्ट" होना चाहिए, लेकिन यह स्पष्ट रूप से केवल एक सिफारिश है, इसलिए प्रत्येक एकल पर स्पष्ट होने की आवश्यकता है <form> टैग।

अन्य कोड विचार :

  • जाहिर है, आप जिन फाइलों की सेवा करेंगे (PHP, HTML, जावास्क्रिप्ट, इत्यादि) को वैध यूटीएफ -8 में एन्कोड किया जाना चाहिए।

  • आपको यह सुनिश्चित करने की ज़रूरत है कि हर बार जब आप यूटीएफ -8 स्ट्रिंग को संसाधित करते हैं, तो आप सुरक्षित रूप से ऐसा करते हैं। दुर्भाग्यवश, यह कठिन हिस्सा है। आप शायद PHP के mbstring एक्सटेंशन का व्यापक उपयोग करना चाहते हैं।

  • PHP के अंतर्निर्मित स्ट्रिंग ऑपरेशंस डिफ़ॉल्ट रूप से यूटीएफ -8 सुरक्षित नहीं हैं। ऐसी कुछ चीजें हैं जो आप सामान्य PHP स्ट्रिंग ऑपरेशंस (जैसे कॉन्सटेनेशन) के साथ सुरक्षित रूप से कर सकते हैं, लेकिन ज्यादातर चीजों के लिए आपको समकक्ष mbstring फ़ंक्शन का उपयोग करना चाहिए।

  • यह जानने के लिए कि आप क्या कर रहे हैं (पढ़ें: इसे गड़बड़ न करें), आपको वास्तव में यूटीएफ -8 को जानना होगा और यह सबसे कम संभव स्तर पर कैसे काम करता है। कुछ अच्छे संसाधनों के लिए utf8.com से किसी भी लिंक को utf8.com , जो आपको जानने की जरूरत है उसे सीखने के लिए।


PHP में यूनिकोड समर्थन अभी भी एक बड़ी गड़बड़ है। हालांकि यह utf8 में ISO8859 स्ट्रिंग (जो आंतरिक रूप से इसका उपयोग करता है) को परिवर्तित करने में सक्षम है, इसमें यूनिकोड स्ट्रिंग्स के साथ काम करने की क्षमता की कमी है, जिसका अर्थ है कि सभी स्ट्रिंग प्रोसेसिंग फ़ंक्शंस आपके तारों को उलझाने और दूषित कर देंगे। तो आपको या तो उचित utf8 समर्थन के लिए एक अलग लाइब्रेरी का उपयोग करना होगा, या सभी स्ट्रिंग हैंडलिंग फ़ंक्शंस को फिर से लिखना होगा।

आसान हिस्सा सिर्फ HTTP शीर्षलेखों में और डेटाबेस में वर्णमाला निर्दिष्ट कर रहा है, लेकिन यदि कोई भी PHP कोड मान्य यूटीएफ 8 आउटपुट नहीं करता है तो कोई भी महत्वपूर्ण नहीं है। यह कठिन हिस्सा है, और PHP आपको वस्तुतः कोई मदद नहीं देता है। (मुझे लगता है कि PHP6 को इसके सबसे बुरे को ठीक करना है, लेकिन यह अभी भी थोड़ी देर दूर है)


मैंने हाल ही में पाया है कि strtolower() का उपयोग strtolower() मुद्दों का कारण बन सकता है जहां एक विशेष चरित्र के बाद डेटा काटा जाता है।

समाधान का उपयोग करना था

mb_strtolower($string, 'UTF-8');

mb_ मल्टीबाइट का उपयोग करता है। यह अधिक पात्रों का समर्थन करता है लेकिन सामान्य रूप से थोड़ा धीमा है।


पूर्णता के लिए, उबंटू पर अपाचे 2 पर, आपको confars उपलब्ध में charset.conf में डिफ़ॉल्ट वर्णसेट मिलेगा।

रेखा को कम करें

AddDefaultCharset UTF-8




php mysql linux apache utf-8