7

关于 UTF-8 字符,我真的很难通过 PDO 让 PHP 与 MySQL 一起玩。

我使用 php --version 得到以下信息:

PHP 5.3.6 (cli) (built: Apr 19 2011 13:21:12)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies

这是来自 mysql cli 的欢迎信息:

Server version: 5.1.57 Source distribution

我有这个作为我的数据库连接代码:

try {
    $dbh = new PDO('mysql:host='.$server.';dbname='.$database.';charset=UTF8', $user, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"));
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

以及我要插入 MySQL 的 php 代码:

$dbh->query("SET NAMES 'UTF8'"); 
$values = array(':idCode' => $idCode, ':name' => $name, ':address' => $address, ':postcode' => $postcode, ':tel' => $tel, ':website' => $website, ':disabled' => $disabled, ':disabledWC' => $disabledWC, ':description' => $description, ':location' => $location, ':type' => $type, ':status' => $status, ':image1name' => $image1name, ':image2name' => $image2name, ':image3name' => $image3name, ':image4name' => $image4name, ':image5name' => $image5name);
$preparedStatement = $dbh->prepare('UPDATE venues SET name = :name, address = :address, postcode = :postcode, tel = :tel, website = :website, disabled = :disabled, disabledWC = :disabledWC, description = :description, location = :location, type = :type, status = :status, date_modified = NOW(), image1name = :image1name, image2name = :image2name, image3name = :image3name, image4name = :image4name, image5name = :image5name WHERE idCode = :idCode');
$preparedStatement->execute($values);

我遇到的问题是,即使我已经验证 $description 确实包含 UTF8 编码字节(使用 bin2hex 和 web 上的 hex2UTF8 工具),数据也不会通过连接作为 UTF-8 提交,我结束了在数据库中使用“Générik”而不是“Générik”。

我尝试在执行之前调用“SET NAMES UTF8”,我已经输入:

[client]
default-character-set=utf8

[mysqld]
default-character-set=utf8

在我的 my.cnf 中,但似乎无法获得任何快乐。

关于如何使它工作的任何提示或技巧?

我应该添加 - 如果我在命令行 MySQL 客户端中手动输入文本,它工作正常,该列设置为采用 UTF8 编码。

根据要求 - 创建表脚本:

| venues | CREATE TABLE `venues` (
  `idCode` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(512) DEFAULT NULL,
  `address` varchar(1024) DEFAULT NULL,
  `postcode` varchar(32) DEFAULT NULL,
  `tel` varchar(32) DEFAULT NULL,
  `website` varchar(1024) DEFAULT NULL,
  `disabled` tinyint(4) DEFAULT NULL,
  `disabledWC` tinyint(4) DEFAULT NULL,
  `description` varchar(4096) CHARACTER SET utf8 DEFAULT NULL,
  `status` tinyint(4) DEFAULT NULL,
  `location` varchar(32) DEFAULT NULL,
  `type` varchar(32) DEFAULT NULL,
  `date_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `image1name` varchar(255) DEFAULT NULL,
  `image2name` varchar(255) DEFAULT NULL,
  `image3name` varchar(255) DEFAULT NULL,
  `image4name` varchar(255) DEFAULT NULL,
  `image5name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`idCode`)
) ENGINE=MyISAM AUTO_INCREMENT=129 DEFAULT CHARSET=latin1

以及 SELECT @@character_set_database 的结果:

SELECT @@character_set_database
    -> ;
+--------------------------+
| @@character_set_database |
+--------------------------+
| utf8                     |
+--------------------------+
1 row in set (0.00 sec)

以及 dumpParams 的结果:

SQL: [410] UPDATE venues SET name = :name, address = :address, postcode = :postcode, tel = :tel, website = :website, disabled = :disabled, disabledWC = :disabledWC, description = :description, location = :location, type = :type, status = :status, date_modified = NOW(), image1name = :image1name, image2name = :image2name, image3name = :image3name, image4name = :image4name, image5name = :image5name WHERE idCode = :idCode
Params:  17
Key: Name: [7] :idCode
paramno=-1
name=[7] ":idCode"
is_param=1
param_type=2
Key: Name: [5] :name
paramno=-1
name=[5] ":name"
is_param=1
param_type=2
Key: Name: [8] :address
paramno=-1
name=[8] ":address"
is_param=1
param_type=2
Key: Name: [9] :postcode
paramno=-1
name=[9] ":postcode"
is_param=1
param_type=2
Key: Name: [4] :tel
paramno=-1
name=[4] ":tel"
is_param=1
param_type=2
Key: Name: [8] :website
paramno=-1
name=[8] ":website"
is_param=1
param_type=2
Key: Name: [9] :disabled
paramno=-1
name=[9] ":disabled"
is_param=1
param_type=2
Key: Name: [11] :disabledWC
paramno=-1
name=[11] ":disabledWC"
is_param=1
param_type=2
Key: Name: [12] :description
paramno=-1
name=[12] ":description"
is_param=1
param_type=2
Key: Name: [9] :location
paramno=-1
name=[9] ":location"
is_param=1
param_type=2
Key: Name: [5] :type
paramno=-1
name=[5] ":type"
is_param=1
param_type=2
Key: Name: [7] :status
paramno=-1
name=[7] ":status"
is_param=1
param_type=2
Key: Name: [11] :image1name
paramno=-1
name=[11] ":image1name"
is_param=1
param_type=2
Key: Name: [11] :image2name
paramno=-1
name=[11] ":image2name"
is_param=1
param_type=2
Key: Name: [11] :image3name
paramno=-1
name=[11] ":image3name"
is_param=1
param_type=2
Key: Name: [11] :image4name
paramno=-1
name=[11] ":image4name"
is_param=1
param_type=2
Key: Name: [11] :image5name
paramno=-1
name=[11] ":image5name"
is_param=1
param_type=2

记录的 $description 的十六进制字节(和预期的字符串值):

 Desctription: 526f756e64696e67206f6666205361747572646179206e6967687420696e20756e666f726765747461626c65207374796c652c204672656e636820636f6d70616e792047c3a96ec3a972696b20566170657572206272696e67207468656972206e65772073686f772057617465726c69747a20746f207468652048617420466169722e204174204b696e672047656f726765205620506c6179696e67204669656c64732c2042617220456e642e: Rounding off Saturday night in unforgettable style, French company Générik Vapeur bring their new show Waterlitz to the Hat Fair. At King George V Playing Fields, Bar End.
4

3 回答 3

7
  try {
      $dbh = new PDO(
          'mysql:host='.$server.';dbname='.$database, 
          $user, 
          $password,
          array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")
      );
      $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  } catch (PDOException $e) {
      print "Error!: " . $e->getMessage() . "<br/>";
      die();
  }

在将数据放入数据库之前不要对数据进行编码,只发送纯原始 utf-8 数据。应该够了。

问候。

于 2012-05-28T11:46:05.603 回答
2

对于这个词Générik,你的“记录的十六进制字节”是0x47c3a96ec3a972696b. 这确实是 UTF-8 编码的。您尝试验证存储数据的客户端几乎可以肯定在获取表内容之前设置了错误的字符集。

于 2012-05-28T13:00:31.313 回答
2

我遇到了同样的问题,我在这篇文章的帮助下解决了这个问题。我正在将完全有效的变音符号输入数据库,但它正在存储垃圾。

我基本上只是添加了这个: array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'")在我的连接/初始化密码之后,因此:

$this->db = new PDO($this->dsn, $this->username, $this->password, 
                    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
于 2013-04-09T19:03:56.997 回答