简体   繁体   English

PHP PDO和COLLATE

[英]PHP PDO and COLLATE

I fail to select some entries in a mysql database, comparing french strings with accentuated characters. 我无法在mysql数据库中选择一些条目,将法语字符串与强调字符进行比较。

Datas samples below are oversimplified for more readability. 下面的数据样本过于简单,以提高可读性。 And I try to be precise, so it's a bit long (sorry). 而且我尽量准确,所以它有点长(对不起)。

Context 上下文

In database, I have some strings like "année", "annee", "début", "debut", etc. The table and columns are charset utf8 with collate utf8_general_ci. 在数据库中,我有一些字符串,如“année”,“annee”,“début”,“debut”等。表和列是charset utf8,带有collat​​e utf8_general_ci。

I'm using MySQL 5.5.30 and PHP 5.4.13 with PDO initializing with charset utf8 : 我正在使用MySQL 5.5.30和PHP 5.4.13与PDO初始化charset utf8:

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

In mysql console client 在mysql控制台客户端

If I SELECT without any collate precision, like 如果我选择没有任何整理精度,如

AND data = :data

with :data = "année". with:data =“année”。 I will get lines with "année" AND "annee". 我会得到“année”和“annee”的行。

Then I SELECT with utf8_bin collate precision, like 然后我用utf8_bin collat​​e精度SELECT,就像

AND data = :data COLLATE utf8_bin

with :data = "année", and I retrieve only lines with "année". with:data =“année”,我只检索带有“année”的行。 COOL. 凉。

With PHP PDO 使用PHP PDO

If I use same SQL in PHP script, with collate precision, I get this error message : 如果我在PHP脚本中使用相同的SQL,并使用整理精度,我会收到以下错误消息:

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

If I use binary collation, like 如果我使用binary排序规则,比如

AND data = :data COLLATE `binary`

I get the error message 我收到错误消息

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

So, my questions are 所以,我的问题是

In PHP script 在PHP脚本中

  • "How to set explicitely the charset ?" “如何明确地设置字符集?” (I believed I did that in PDO string initialization, but it seems to be wrong. "SET NAMES ..." does not work any better in this case) (我相信我在PDO字符串初始化中做到了这一点,但似乎是错误的。“SET NAMES ......”在这种情况下效果不好)
  • "How can I retrieve correct results with PDO when comparing with accentuated characters?" “与强调字符比较时,如何使用PDO检索正确的结果?”

Precisions 精度

Here are more details (ask in comments). 这里有更多细节(在评论中提问)。

*Extract from the "show create table" *摘自“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

*Two sample SELECT (from console, not with PHP / PDO): *两个示例SELECT(来自控制台,而不是PHP / PDO):

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

which returns 返回

+-----------+---------------------------+
| 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               |
+-----------+---------------------------+

And

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

which returns 返回

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

*The charsets : *字符集:

+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+

I had the same problem and I succeeded by wrapping the parameter with convert(), like so: 我有同样的问题,我成功用convert()包装参数,如下所示:

data = convert(:data using utf8) collate utf8_bin

It appears that PDO always tags string parameters with character set BINARY by PDO. 似乎PDO始终用PDO标记字符集BINARY的字符串参数。 It would be really nice to find out how to change this. 找出如何改变它真的很好。

Also, I'm not sure if it's actually correct to convert the string to UTF8 like this, I suppose technically it could depend on how PHP represents the string internally. 另外,我不确定将字符串转换为UTF8是否实际上是正确的,我认为技术上它可能取决于PHP如何在内部表示字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM