【问题标题】:PHP PDO and COLLATEPHP PDO 和整理
【发布时间】:2015-11-30 10:48:45
【问题描述】:

我无法在 mysql 数据库中选择一些条目,比较法语字符串和重音字符。

为了提高可读性,下面的数据示例被过度简化了。而且我尽量准确,所以有点长(抱歉)。

上下文

在数据库中,我有一些字符串,如“annee”、“annee”、“début”、“debut”等。表和列是 charset utf8 和 collat​​e utf8_general_ci。

我正在使用 MySQL 5.5.30 和 PHP 5.4.13 以及使用 charset utf8 初始化的 PDO:

$this->dbh = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->base . ';charset=utf8', $this->user, $this->pass);

在 mysql 控制台客户端中

如果我 SELECT 没有任何整理精度,比如

AND data = :data

使用 :data = "annee"。我会得到带有“annee”和“annee”的台词。

然后我 SELECT 使用 utf8_bin 整理精度,比如

AND data = :data COLLATE utf8_bin

使用 :data = "annee",我只检索带有 "annee" 的行。酷。

使用 PHP PDO

如果我在 PHP 脚本中使用相同的 SQL,并且具有整理精度,我会收到以下错误消息:

 COLLATION 'utf8_bin' is not valid for CHARACTER SET 'binary'

如果我使用binary 排序规则,比如

AND data = :data COLLATE `binary`

我收到错误消息

 COLLATION 'binary' is not valid for CHARACTER SET 'utf8'

所以,我的问题是

在 PHP 脚本中

  • “如何明确设置字符集?” (我相信我在 PDO 中做到了 字符串初始化,但似乎是错误的。 “SET NAMES ...”在这种情况下不会更好)
  • “与重音字符进行比较时,如何使用 PDO 检索正确的结果?”

精度

这里有更多细节(在 cmets 中询问)。

*从“show create table”中提取

CREATE TABLE `Request` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`client_id` int(8) DEFAULT NULL,
....
`domain_version_corrective` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8

*两个示例 SELECT(来自控制台,不使用 PHP / PDO):

SELECT domain_id, domain_version_corrective FROM Request WHERE client_id = 3661 AND domain_version_corrective = 'vèrçion 2.0' ;

返回

+-----------+---------------------------+
| domain_id | domain_version_corrective |
+-----------+---------------------------+
| FOOBAR    | vercion 2.0               |
| FOOBAR    | vèrcion 2.0               |
| FOOBAR    | verçion 2.0               |
| FOOBAR    | vèrçion 2.0               |
| FOOBAR    | vèrcion 2.0               |
+-----------+---------------------------+

SELECT domain_id, domain_version_corrective FROM Request WHERE client_id = 3661 AND domain_version_corrective = 'vèrçion 2.0' COLLATE utf8_bin;

返回

+-----------+---------------------------+
| domain_id | domain_version_corrective |
+-----------+---------------------------+
| FOOBAR    | vèrçion 2.0               |
+-----------+---------------------------+

*字符集:

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

【问题讨论】:

  • 请提供SHOW CREATE TABLE 和完整的SELECTSHOW VARIABLES LIKE 'char%';。有人称它为BINARY,而不是VARCHAR。请务必使用与程序相同的用户登录。它不应该是“根”。另外,你的 my.cnf 中有 init_connect 吗?
  • @RickJames,我在问题本身添加了询问的详细信息。我在控制台和 php 脚本(不是 root)中使用相同的凭据。并且有空字符串作为 init_connect 变量。感谢您的关注!
  • 您是否尝试过将PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8" 作为您在PDO 中的连接选项?
  • @EhsanT,是的,但没有成功:(
  • 那么,在打开您的连接后添加这行:$dbh->exec("set names utf8"); 怎么样?

标签: php mysql pdo utf-8


【解决方案1】:

我遇到了同样的问题,我成功地用 convert() 包装了参数,如下所示:

data = convert(:data using utf8) collate utf8_bin

似乎 PDO 总是用 PDO 的字符集 BINARY 标记字符串参数。想知道如何改变这一点真是太好了。

另外,我不确定像这样将字符串转换为 UTF8 是否真的正确,我想从技术上讲它可能取决于 PHP 如何在内部表示字符串。

【讨论】:

  • 我刚刚尝试了这个解决方案并得到了想要的结果!谢谢乔基
猜你喜欢
  • 2013-11-06
  • 2016-02-29
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
相关资源
最近更新 更多