PHP PDO: चारसेट, सेट नाम?


188

मेरे पास यह पहले मेरे सामान्य mysql_ * कनेक्शन में था:

mysql_set_charset("utf8",$link);
mysql_query("SET NAMES 'UTF8'");

क्या मुझे पीडीओ के लिए इसकी आवश्यकता है? और मेरे पास कहाँ होना चाहिए?

$connect = new PDO("mysql:host=$host;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

10
SQL इंजेक्शन के कारण "SET NAMES utf8" से बचा जाना चाहिए। वह विवरण के लिए php.net/manual/en/mysqlinfo.concepts.charset.php देखें ।
मस्कैलास्टिक

यदि आपके पास चारसेट मुद्दे हैं तो आपके पास utf8 पर सेट करने के अलावा कोई विकल्प नहीं हो सकता है। मुझे लगता है कि दूर ले जाना चाहिए कनेक्शन स्ट्रिंग का उपयोग करना चाहिए जैसा कि नीचे कोबरा_फैस्ट द्वारा दिखाया गया है । पीडीओ का उपयोग करें :: बाध्य मापदंडों के साथ अपने एसक्यूएल बयान तैयार करने के लिए तैयार करें।
user12345

1
@masakielastic, फिर हमें "SET NAMES utf8 COLLATE utf8_unicode_ci" के रूप में टकराव को कैसे निर्दिष्ट करना चाहिए
डेटानेट.आईओ

जवाबों:


459

आप इसे अपने कनेक्शन स्ट्रिंग में पसंद करेंगे:

"mysql:host=$host;dbname=$db;charset=utf8"

कैसे, PHP 5.3.6 से पहले, चारसेट विकल्प को नजरअंदाज कर दिया गया था। यदि आप PHP का पुराना संस्करण चला रहे हैं, तो आपको इसे इस तरह करना होगा:

$dbh = new PDO("mysql:$connstr",  $user, $password);
$dbh->exec("set names utf8");

15
यह ध्यान देने योग्य है कि यह व्यवहार 5.3.6 में बदल गया, और अब सही ढंग से काम कर रहा है।
igorw

15
shoudle UTF-8 के "mysql: होस्ट = $ होस्ट; utb8 इंस्टाएड हो; dbname = $ db; charset = utf8"
od3n

3
यदि आप PHP के अप-टू-डेट संस्करण का उपयोग कर रहे हैं, तो नीचे दिए गए उत्तरों को अनदेखा करें: यह php 5.3.8 में ठीक काम करता है।
कासिमिर

4
क्या मुझे इस मामले में भी कॉलेशन को निर्दिष्ट करना होगा? जैसे कि 'SET NAMES utf8 COLLATE utf8_unicode_ci'?
datasn.io

2
धन्यवाद! मेरा दिन बचाया!
Aleksandr

64

PHP 5.3.6 से पहले, चारसेट विकल्प को नजरअंदाज कर दिया गया था। यदि आप PHP का पुराना संस्करण चला रहे हैं, तो आपको इसे इस तरह करना होगा:

<?php

    $dbh = new PDO("mysql:$connstr",  $user, $password);

    $dbh -> exec("set names utf8");

?>

1
नोट टू मॉड्स: यह सही उत्तर है, और स्वीकृत उत्तर से एक वर्ष पहले इसे पोस्ट किया गया था, इस जानकारी को इसमें संपादित किया गया था।
dotancohen

42

यह शायद इसे करने का सबसे सुरुचिपूर्ण तरीका है।
पीडीओ कंस्ट्रक्टर कॉल में सही, लेकिन छोटी गाड़ी के विकल्प से बचने (जैसा कि ऊपर बताया गया है):

$connect = new PDO(
  "mysql:host=$host;dbname=$db", 
  $user, 
  $pass, 
  array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
  )
);

मेरे लिए बहुत अच्छा काम करता है।


1
मेरी समझ यह है कि यह भी php 5.3.0 के लिए छोटी गाड़ी है। उस स्थिति में आपको इसके नाम की तरह इसके नंबर को संदर्भित करके सरणी में विकल्प दर्ज करना होगा array(1002 => 'SET NAMES utf8',...):।
JDelage

संकेत के लिए धन्यवाद! मैं PHP के विभिन्न 5.3.X संस्करणों को चलाने वाले कई उत्पादन प्रणालियों पर सफलतापूर्वक उपरोक्त कोड का उपयोग कर रहा हूं, लेकिन वास्तव में उनमें से कोई भी 5.3.0 नहीं है।
जेपीसी

4
मेरा मानना ​​है कि यह डेटाबेस विशिष्ट विकल्पों के बिना अधिक सुरुचिपूर्ण हो सकता है
Aalex Gabi

सही है, MYSQL_ATTR_INIT_COMMAND केवल MySQL डेटाबेस के लिए उपलब्ध है (प्रत्येक db प्रकार के लिए उपलब्ध कमांड php.net/manual/de/pdo.drivers.php के उप-पृष्ठ देखें )। लेकिन यह वही है जो ओपी ने पूछा है।
11

charset=utf8dsn स्ट्रिंग काम करता है में गुजर रहा है! मैं इस मुद्दे पर समूहों में
Hari KT

16

पूर्णता के लिए, वास्तव में PDO से MySQL से कनेक्ट करते समय एन्कोडिंग सेट करने के तीन तरीके हैं और जो उपलब्ध हैं वे आपके PHP संस्करण पर निर्भर हैं। वरीयता का क्रम होगा:

  1. charset DSN स्ट्रिंग में पैरामीटर
  2. कनेक्शन विकल्प के SET NAMES utf8साथ चलाएँPDO::MYSQL_ATTR_INIT_COMMAND
  3. SET NAMES utf8मैन्युअल रूप से चलाएं

यह नमूना कोड तीनों को लागू करता है:

<?php

define('DB_HOST', 'localhost');
define('DB_SCHEMA', 'test');
define('DB_USER', 'test');
define('DB_PASSWORD', 'test');
define('DB_ENCODING', 'utf8');


$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_SCHEMA;
$options = array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);

if( version_compare(PHP_VERSION, '5.3.6', '<') ){
    if( defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
        $options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . DB_ENCODING;
    }
}else{
    $dsn .= ';charset=' . DB_ENCODING;
}

$conn = @new PDO($dsn, DB_USER, DB_PASSWORD, $options);

if( version_compare(PHP_VERSION, '5.3.6', '<') && !defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
    $sql = 'SET NAMES ' . DB_ENCODING;
    $conn->exec($sql);
}

तीनों को करना शायद ओवरकिल है (जब तक कि आप एक वर्ग नहीं लिख रहे हैं जिसे आप वितरित या पुन: उपयोग करने की योजना बनाते हैं)।


1
क्या कोई ODBC / Access समतुल्य है? अब मेरे पास एक काम करने वाला ओरेकल और MySQL PHP PDO UTF8 कनेक्शन है, लेकिन मैं इसे ODBC / Access के लिए काम नहीं कर सकता।
Jan

2
ओह, और कभी भी अपने डेटाबेस पासवर्ड को न भूलें। वे सुपरग्लोबल्स के रूप में वैश्विक हैं, और जब आप पासवर्ड के साथ काम कर रहे हों तो यह अच्छी बात नहीं है।
Xesau

2

मैं केवल यह जोड़ना चाहता हूं कि आपको यह सुनिश्चित करना होगा कि आपका डेटाबेस COLLATE utf8_general_ci या जो भी आप उपयोग करना चाहते हैं, जो भी आप उपयोग करना चाहते हैं उसके साथ बनाया गया है, तो आप किसी अन्य उद्देश्य के साथ समाप्त हो सकते हैं।

Phpmyadmin में आप अपने डेटाबेस पर क्लिक करके कॉलेशन देख सकते हैं और ऑपरेशन चुन सकते हैं। यदि आप अपने डेटाबेस की तुलना में किसी अन्य टकराव के साथ तालिकाओं को बनाने का प्रयास करते हैं, तो आपकी तालिकाएँ डेटाबेस कोलाज़ के साथ समाप्त हो जाएँगी।

इसलिए सुनिश्चित करें कि टेबल बनाने से पहले आपके डेटाबेस के लिए टकराव सही है। आशा है कि यह किसी को कुछ घंटों के लिए बचाता है


1
"यदि आप अपने डेटाबेस की तुलना में किसी अन्य टकराव के साथ तालिकाओं को बनाने का प्रयास करते हैं, तो आपकी तालिकाएँ डेटाबेस कोलाज़ वैसे भी समाप्त हो जाएंगी" - मुझे नहीं लगता कि यह सही है। डेटाबेस के टकराव पर तालिका का टकराव पूर्वता लेता है। dev.mysql.com/doc/refman/5.5/en/charset-table.html
humble_wolf

2

मुझे लगता है कि आपको अतिरिक्त क्वेरी की आवश्यकता है क्योंकि DSN में चारसेट विकल्प वास्तव में अनदेखा है। अन्य उत्तर की टिप्पणी में पोस्ट लिंक देखें।

Drupal 7 इसे http://api.drupal.org/api/drupal/includes--database--mysql--database.inc/function/DatabaseConnection_matql%3A%3A__construction/7 में कैसे देख रहा है :

// Force MySQL to use the UTF-8 character set. Also set the collation, if a
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
// for UTF-8.
if (!empty($connection_options['collation'])) {
  $this->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
}
else {
  $this->exec('SET NAMES utf8');
}

1
$conn = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);

1
हालांकि यह उत्तर शायद सही और उपयोगी है, यह पसंद किया जाता है यदि आप इसे समझाने के साथ कुछ स्पष्टीकरण भी शामिल करते हैं कि यह समस्या को हल करने में कैसे मदद करता है। यह भविष्य में विशेष रूप से उपयोगी हो जाता है, अगर कोई परिवर्तन (संभवतः असंबंधित) होता है जो इसे काम करना बंद कर देता है और उपयोगकर्ताओं को यह समझने की आवश्यकता है कि एक बार कैसे काम किया।
एर्टि सीडोहेल

1
$con="";
$MODE="";
$dbhost = "localhost";
$dbuser = "root";
$dbpassword = "";
$database = "name";

$con = new PDO ( "mysql:host=$dbhost;dbname=$database", "$dbuser", "$dbpassword", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$con->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );   

0

मैं इस कोड का परीक्षण करता हूं और

$db=new PDO('mysql:host=localhost;dbname=cwDB','root','',
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$sql="select * from products  ";
$stmt=$db->prepare($sql);
$stmt->execute();
while($result=$stmt->fetch(PDO::FETCH_ASSOC)){                  
    $id=$result['id'];
}

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, क्यों और / या इस कोड के उत्तर के बारे में अतिरिक्त संदर्भ प्रदान करने से प्रश्न इसके दीर्घकालिक मूल्य में सुधार करता है।
रोलस्टुफ़्लोरहेयर

-1

$ con = new PDO ("mysql: host = $ dbhost; dbname = $ database; charset = $ एन्कोडिंग ", "$ dbuser", "$ dbpassword");

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.