我以前在正常的mysql_ *连接中具有此功能:

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


评论

由于SQL注入,应避免使用“ SET NAMES utf8”。有关详细信息,请参见php.net/manual/en/mysqlinfo.concepts.charset.php。

如果您遇到字符集问题,则可能别无选择,只能设置为utf8。我认为应该使用下面的Cobra_Fast所示的连接字符串。使用PDO :: prepare准备带有绑定参数的SQL语句。

@masakielastic,那么我们应该如何将归类指定为“ SET NAMES utf8 COLLATE utf8_unicode_ci”

#1 楼

您将在连接字符串中添加它,例如:

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


但是,在PHP 5.3.6之前,charset选项被忽略。如果您正在运行旧版本的PHP,则必须这样做:

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


评论


值得注意的是,此行为在5.3.6中已更改,现在可以正常工作。

–igorw
2011年11月10日10:47



应该是UTF-8的utf8 instaead,“ mysql:host = $ host; dbname = $ db; charset = utf8”

–od3n
2012-2-17的3:33



如果您使用的是最新版本的PHP,请忽略以下答案:在PHP 5.3.8中它可以正常工作。

– kasimir
2012年5月2日15:02

在这种情况下,我还必须指定排序规则吗?例如“设置名称utf8 COLLATE utf8_unicode_ci”?

–datasn.io
2014年9月12日上午11:15

谢谢!拯救了我的一天!

– Aleksandr
17年1月19日在19:36

#2 楼

在PHP 5.3.6之前,charset选项被忽略。如果您正在运行旧版本的PHP,则必须这样做:

<?php

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

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

?>


评论


国防部注意事项:这是正确的答案,它是在接受的答案将此信息编辑到一年之前发布的。

– dotancohen
2013年12月24日6:38



#3 楼


就在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"
  )
);


非常适合我。

评论


我的理解是,这对于php 5.3.0也是错误的。在这种情况下,您需要通过引用其编号而不是像这样的名称来在数组中输入该选项:array(1002 =>'SET NAMES utf8',...)。

– JDelage
2012年2月24日23:50

感谢您的提示!我在运行不同5.3.X版本PHP的多个生产系统上成功使用了上面的代码,但实际上它们都不是5.3.0。

–Jpsy
2012-2-26在16:08

我认为如果没有特定于数据库的选项,它可能会更优雅

– Aalex Gabi
2012年9月6日下午16:51

的确,MYSQL_ATTR_INIT_COMMAND仅适用于MySQL数据库(有关每种数据库类型的可用命令,请参见php.net/manual/de/pdo.drivers.php的子页面)。但这正是OP所要求的。

–Jpsy
2012年11月6日,11:54



在dsn字符串中传递charset = utf8是可行的!我试图通过groups.google.com/d/msg/auraphp/syMS26Rz-q8/9laQr9tR4EoJ找出问题

–哈里K T
13年11月14日下午5:17

#4 楼

为了完整起见,从PDO连接到MySQL时,实际上有三种方法来设置编码,哪种可用取决于您的PHP版本。优先顺序为:




DSN字符串中的charset参数
使用SET NAMES utf8连接选项运行PDO::MYSQL_ATTR_INIT_COMMAND
手动运行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);
}


做到这三个都可能是多余的(除非您要编写计划分发或重用的类)。

评论


是否有等效的ODBC / Access?我现在有一个可以正常工作的Oracle和MySQL PHP PDO UTF8连接,但是我无法使它适用于ODBC / Access。

– Jan
15年5月28日在13:32

哦,永远不要定义您的数据库密码。它们与超全局变量一样具有全局性,而当您使用密码时,这并不是一件好事。

– Xesau
15年8月24日在19:56



#5 楼

我只想补充一下,您必须确保使用COLLATE utf8_general_ci或要使用的任何排序规则创建数据库,否则您可能会得到比预期的另外一个排序规则。通过单击数据库并选择操作来排序。如果尝试使用数据库以外的其他排序规则创建表,则表最终仍将以数据库排序规则结束。

因此,在创建表之前,请确保数据库的排序规则正确。希望这可以节省一个人几个小时大声笑

评论


“如果您尝试使用数据库以外的其他排序规则创建表,那么您的表无论如何都会以数据库排序规则结尾”-我认为这是不正确的。表排序规则优先于数据库的排序规则。 dev.mysql.com/doc/refman/5.5/en/charset-table.html

–humble_wolf
17-10-7在9:32

#6 楼

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


评论


尽管此答案可能是正确且有用的,但如果您在其中包含一些解释以说明它如何帮助解决问题,则最好使用该答案。如果发生更改(可能不相关)导致它停止工作,并且用户需要了解它曾经如何工作,那么这在将来特别有用。

–Erty Seidohl
18年5月23日在22:03

#7 楼

我认为您需要一个附加查询,因为DSN中的charset选项实际上被忽略了。请参阅其他答案的注释中发布的链接。

在http://api.drupal.org/api/drupal/includes--database--mysql-中查看Drupal 7的工作方式。 -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');
}


#8 楼

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


#9 楼

我测试了这段代码,然后

$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'];
}


评论


尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以提高其长期价值。

–rollstuhlfahrer
18年4月6日在7:07