[英]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,带有collate 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 collate精度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脚本中
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.