2010-12-05 28 views
152

我在正常mysql_ *連接以前有這樣的:PHP PDO:字符集,集名稱?

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

我需要它的PDO?我應該在哪裏?

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

由於SQL注入,應避免使用「SET NAMES utf8」。詳情請參閱http://www.php.net/manual/en/mysqlinfo.concepts.charset.php。 – masakielastic 2013-06-08 09:47:44

+0

如果你有字符集問題,那麼你可能別無選擇,只能設置爲utf8。我認爲應該使用下面的[連接字符串,如Cobra_Fast所示](https://stackoverflow.com/a/4361485/1048805)。使用PDO :: prepare準備帶有綁定參數的SQL語句。 – user12345 2014-07-02 23:16:50

+1

@masakielastic,那麼我們應該如何指定排序規則爲「SET NAMES utf8 COLLATE utf8_unicode_ci」 – 2014-09-12 11:17:13

回答

368

你必須像你的連接字符串中:

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

然而,之前PHP 5.3.6,字符集選項被忽略。如果你運行PHP的舊版本,你都必須做這樣的:

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

值得注意的是,此行爲在5.3.6中進行了更改,現在正在正常工作。 – igorw 2011-11-10 10:47:35

+14

UTF-8「UTF-8」:host:host = $ host; dbname = $ db; charset = utf8「 – od3n 2012-02-17 03:33:03

+3

如果您使用的是最新版本的PHP,請忽略下面的答案:它工作得很好PHP 5.3.8。 – kasimir 2012-05-02 15:02:09

2

我想你需要一個額外的查詢,因爲在DSN的charset選項實際上是忽略不計。看到在其他答案的評論中發佈的鏈接。

看着Drupal 7的如何做它http://api.drupal.org/api/drupal/includes--database--mysql--database.inc/function/DatabaseConnection_mysql%3A%3A__construct/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'); 

}

59

到PHP 5.3.6之前,charset選項被忽略。如果你運行的是PHP的老版本,你必須這樣做:

<?php 

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

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

?> 
33

這可能是最優雅的方式來做到這一點。
權的PDO構造函數調用,但避免了馬車charset選項(如上所述):

$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" 
) 
); 

爲我的偉大工程。

16

爲了完整起見,實際上有三種從PDO連接到MySQL時設置編碼的方法,哪些可用取決於您的PHP版本。優先順序是:在DSN字符串

  1. charset參數
  2. 運行SET NAMES utf8PDO::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); 
} 

做這三件事可能是矯枉過正的(除非你正在編寫一個你計劃分發或重用的類)。

2

我只是想補充一點,你必須確保你的數據庫是用COLLATE utf8_general_ci創建的,或者是你想使用的排序規則,否則你最終可能會得到比預期更多的排序規則。

在phpmyadmin中,您可以通過單擊數據庫並選擇操作來查看排序規則。如果嘗試使用另一個排序規則創建表而不是數據庫,則無論如何您的表最終都會與數據庫排序對齊。

因此,在創建表之前確保數據庫的排序規則正確。希望這樣可以節省別人幾個小時笑

0
$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); 
-1

$ CON =新PDO( 「mysql的:主機= $ DBHOST; DBNAME = $數據庫; 的charset = $編碼」, 「$ DBUSER」,「$ DBPASSWORD 「);