Mat*_*att 10 mysql sql wordpress database-migration character-encoding
我有标准的MySQL导入编码问题,但我似乎无法解决它.
我的客户已经运行了一段时间的WordPress安装.我已将数据库转储到文件中,并在本地导入.生成的页面中包含 字符的泼溅.
我已经检查过双方的数据库属性:production:show create database wordpress;
CREATE DATABASE `wordpress` /*!40100 DEFAULT CHARACTER SET latin1 */
Run Code Online (Sandbox Code Playgroud)
local:show create database wordpress;
CREATE DATABASE `wordpress` /*!40100 DEFAULT CHARACTER SET latin1 */
Run Code Online (Sandbox Code Playgroud)
制作:show create table wp_posts;
CREATE TABLE `wp_posts` (
`ID` bigint(20) unsigned NOT NULL auto_increment,
...
KEY `post_date_gmt` (`post_date_gmt`)
) ENGINE=MyISAM AUTO_INCREMENT=7932 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
local:show create table wp_posts;
CREATE TABLE `wp_posts` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
...
KEY `post_date_gmt` (`post_date_gmt`)
) ENGINE=MyISAM AUTO_INCREMENT=7918 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
我花了几个小时阅读关于如何压制 的论坛,但我无法得到任何工作.99%的答案表示匹配数据库之间的字符集.如果以下情况我认为应该有用:
mysqldump --opt --compress --default-character-set=latin1 -uusername -ppassword wordpress | ssh username@anotherserver.net mysql --default-character-set=latin1 -uusername -ppassword wordpress
Run Code Online (Sandbox Code Playgroud)
我也使用utf8字符集完成了它.仍然与 的.
我已经尝试直接修改SQL转储,将utf8或latin1放在"SET names UTF8"行中.仍然与 的.
奇怪的症状
我希望这些 字符代替内容中的特殊字符出现,比如ñ或ö,但我已经看到它通常只有一个空格.我也看到它取代了撇号(但不是所有撇号),双引号和商标符号.
标记非常罕见.它们每页平均出现三到四次.
通过Sequel Pro(本地或现场)查看数据库时,我看不到任何 ..通过Textmate查看时,我在SQL中看不到任何 's.
我错过了什么?
编辑
更多信息:
我试图确定实时数据库认为编码是什么.我跑了show table status
,似乎Collations是utf8_general_ci,
utf8_bin latin1_swedish_ci` 的混合体and
.它们有什么不同?有关系吗?
我也跑了:show variables like "character_set_database"
得到了latin1
;
Mat*_*att 11
这就是我最终解决问题的方法:
第一 mysqldump -uusername -ppassword --default-character-set=latin1 database -r dump.sql
然后运行此脚本:
$search = array('/latin1/');
$replace = array('utf8');
foreach (range(128, 255) as $dec) {
$search[] = "/\x".dechex($dec)."/";
$replace[] = "&#$dec;";
}
$input = fopen('dump.sql', 'r');
$output = fopen('result.sql', 'w');
while (!feof($input)) {
$line = fgets($input);
$line = preg_replace($search, $replace, $line);
fwrite($output, $line);
}
fclose($input);
fclose($output);
Run Code Online (Sandbox Code Playgroud)
该脚本查找127以上的所有十六进制字符,并将它们编码到HTML实体中.
然后 mysql -uusername -ppassword database < result.sql
较旧的WordPress数据库甚至是较新的WordPress数据库的一个普遍问题是,数据库表被设置为latin-1,但其内容实际上被编码为UTF-8。如果您尝试导出为UTF-8,MySQL将尝试将(假定的)Latin-1数据转换为UTF-8,从而产生双编码字符,因为该数据已经是UTF-8。
解决方案是将表导出为latin-1。由于MySQL认为它们已经是latin-1,因此它将直接导出。
从'latin1更改字符集?到'utf8 ?。由于转储的数据在导出过程中未进行转换,因此实际上是UTF-8编码的数据。
将新表创建为UTF-8如果您的CREATE TABLE命令在您的SQL转储文件中,请从'latin1?更改字符集?到'utf8 ?。
正常导入数据。由于转储文件中已经有UTF-8编码的数据,转储文件中声明的字符集现在为UTF-8,并且您要导入的表为UTF-8,因此一切都会顺利进行