我有一个带有以下列的表:
users(
id SERIAL,
username VARCHAR(20),
password VARCHAR(64),
salt VARCHAR(32),
name VARCHAR(50),
joined TIMESTAMP WITHOUT TIME ZONE,
grupo INTEGER
)
数据库编码是UTF8。
PDO连接:
private function __construct(){
try{
$this->_pdo = new PDO('pgsql:host=' . Config::get('pgsql/host') . ';port=' . Config::get('pgsql/port') . ';dbname=' . Config::get('pgsql/db') . ';user=' . Config::get('pgsql/username'). ';password=' . Config::get('pgsql/password'));
$this->_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
die($e->getMessage());
}
}
我正在使用PDO,而我的脚本是以下内容,用于插入数据:
public function query($sql, $params = array()){
$this->_error = false;
if($this->_query = $this->_pdo->prepare($sql)){
$this->_query->execute($params);
}
}
SQL通过的是:
INSERT INTO users(username, password, salt, name, joined, grupo) VALUES(?, ?, ?, ?, ?, ?)
,传递的数组是:
Array ( [0] => nath
[1] => 81033b63c09fd9104977fdb0ef70b5dc627fd9a6e90d0d400706603def8c22a6
[2] => KwjWC57AO0Gh1VvSUuJpDMNkEiraBzFL
[3] => Nathália
[4] => 2014-03-06 19:35:01
[5] => 1 )
运行此功能时,我会收到以下错误:
SQLSTATE[22021]: Character not in repertoire: 7 ERRO: invalid byte sequence invalid for UTF encode. "UTF8": 0xe1 0x6c 0x69
ps:如果我键入纳塔利亚而不是纳塔利亚,它可以很好地工作。
试图弄清楚发生了什么,我按字段插入了字段,这样:
if($this->_query = $this->_pdo->prepare("INSERT INTO users(username) VALUES(?)"){
$this->_query->execute(array('nath'));
}
它运行还可以。然后,我用password
和array('nath')
用array('81033b63c09fd9104977fdb0ef70b5dc627fd9a6e90d0d400706603def8c22a6')
替换username
,而其他字段则相同。
当我按字段插入字段时,一切正常。发生了什么线索?
错误消息与问题有关:
0xe1 0x6c 0x69
0xe1是ISO-8859-1中的á
,而不是UTF-8中。
其他两个字节代表US-ASCII范围(l
和i
)中的字符,因此它们在ISO-8859-1和UTF-8中共享相同的字节代表。
您的脚本正在发送iso-8859-1
编码文本,而不是utf-8
编码的文本。您应该质疑从哪里获得Nathália
字符串以及应该如何编码。
如果应该在utf-8
中,则是该字符串的生产者的错误。如果应该在ISO-LATIN中,则您的脚本必须将utf8_encode
应用于utf-8
数据库连接之前。