mysql字符集含义请看mysql手册第10.1节Character Set Supportphp
mysql的字符集转换过程请看鸟哥博客的这一篇html
debian使用apt安装的mysql一开始是这样的mysql
能够看到默认状况下sql
sever的字符集是latin1数据库
db的字符集是latin1vim
mysql cli的client和connect的字符集是utf8url
(pdo链接的client和connect的默认字符集是latin1)3d
server的字符集设置能够经过配置文件修改server
vim /etc/mysql/my.cnf
在[mysqld]部分添加htm
character_set_server = utf8
重启mysql
能够看到server的默认字符集变成了utf8
设置server字符集后,数据库的默认字符集也变成了和server相同的utf8
此外,在修改server字符集的状况下,还能够经过建立数据库时指定字符集的方式设置数据库字符集
以下图,server和database的默认字符集都是latin1
建立数据库test
create database test character set utf8;
此时默认的server和db字符集还是latin1
可是此时数据库test的默认字符集已经被修改成utf8
设置了数据库的字符集,表的字符集若未设置则使用数据库的字符集
此外,还能够在建立表时指定表的字符集CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(64) NOT NULL DEFAULT '', `email` varchar(64) NOT NULL DEFAULT '', `age` tinyint(3) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
设置了表的字符集,表列的字符集默认使用表的字符集
此外,还能够在建立表时指定列的字符集
CREATE TABLE `user2` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(64) CHARACTER SET latin1 NOT NULL DEFAULT '', `email` varchar(64) CHARACTER SET latin1 NOT NULL DEFAULT '', `age` tinyint(3) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;下图可见,表字符集为utf8,列字符集为latin1
客户端和链接的字符集须要在客户端设置,不然默认为latin1
$dsn = 'mysql:host=127.0.0.1;dbname=test'; $user = 'root'; $password = 'root'; $pdo = new PDO($dsn, $user, $password); $name = $_GET['name']; $email = $_GET['email']; $age = $_GET['age']; $sql = 'insert into user (name,email,age) values (:name,:email,:age)'; $stmt = $pdo->prepare($sql); $stmt->bindParam(':name', $name, PDO::PARAM_STR); $stmt->bindParam(':email', $email, PDO::PARAM_STR); $stmt->bindParam(':age', $age, PDO::PARAM_INT); $stmt->execute();
经过访问
http://www.test.com/?name=你好&email=123@test.com&age=20
执行上述代码,在mysql cli的字符集为utf8时name显示乱码,
客户端在链接到mysql后,执行
set names utf8;
php代码中表示为
$pdo = new PDO($dsn, $user, $password); $pdo->exec('set names utf8');
再次访问url,可见链接字符集已设置为utf8
此外,还能够经过pdo链接时设置字符集
$dsn = 'mysql:host=127.0.0.1;dbname=test;charset=utf8'; $user = 'root'; $password = 'root'; $pdo = new PDO($dsn, $user, $password);
以及这样
$attr = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'); $pdo = new PDO($dsn, $user, $password, $attr);
参考资料
msyql手册 http://dev.mysql.com/doc/refman/5.5/en/charset.html
laruence博客 http://www.laruence.com/2008/01/05/12.html
stackoverflow http://stackoverflow.com/questions/4361459/php-pdo-charset-set-names
http://stackoverflow.com/questions/18496557/pdo-utf-8-encoding-issue