【问题标题】:Convert wrong encoding - MySQL转换错误的编码 - MySQL
【发布时间】:2021-07-03 16:06:42
【问题描述】:

我有一个带有 MySQL 数据库的站点,其中已经有很多数据,我在数据库的编码方面犯了一个错误,现在所有数据都不能通过“PHPMyAdmin”读取

现在我解决了编码问题,所有新数据都可读但旧数据不可读,问题出在与数据库的连接上,因为我没有添加“utf8”聊天集...

如果我从连接中删除 mysqli_set_charset($con,"utf8");,数据 OLD 是可读的 但随后 NEW 数据不可读。

有没有办法将错误的编码数据转换为正确的 UTF8?

例如带有 GOOD 和 BAD 行的图像:

【问题讨论】:

  • 列数据类型?语言环境?
  • 所有错误的编码列类型都是 VARCHAR 并且排序规则是 utf8_general_ci
  • 你可以试试 utf8_encode 呃,即使说这个函数的名字不好。这当然是如果以前的字符集是 latin1
  • 如果旧数据可以通过一种方式读取,则以这种方式读取,并以新方式调用UPDATE。这将是修复数据库的一次性事情,因此代码会让人觉得浪费且非最佳,但事实就是如此。
  • 相关:UTF-8 all the way through。顺便说一句,有人可以找到一个可能的 mojibake 实例 - 如果您在 minimal reproducible example 中添加 textual 不可读字符串的示例…

标签: php mysql sql encoding phpmyadmin


【解决方案1】:

好吧,我认为最好的解决方案是手动更新,

进行数据库备份、配置并将此文件放在您的网络服务器的任何位置并使用它。

编辑我忘了在这个表中添加一个名为 reconfigured 的新列

<?php

$server = "localhost";
$username = "root";
$password = "";
$database = "database";

$table = "corrupted table";

//utf8
$con = mysqli_connect($server, $username, $password, $database);
mysqli_set_charset($con,"utf8");
//auto
$con2 = mysqli_connect($server, $username, $password, $database);

if (isset($_GET['id']) and isset($_GET['which'])) {
  switch($_GET['which']) {
    case 1: $correct_string = mysqli_query($con, "SELECT name FROM `".$table." WHERE `id`='".$_GET['id']."'"); $correct_string = mysqli_fetch_row($con, $correct_string); break;
    case 2: $correct_string = mysqli_query($con2, "SELECT name FROM `".$table." WHERE `id`='".$_GET['id']."'"); $correct_string = mysqli_fetch_row($con2, $correct_string); break;
  }
  mysqli_query($con, "UPDATE `".$table."` SET `name` = '".$correct_string['0']."' WHERE `".$table."`.`id` = '".$_GET['id']."'");
  mysqli_query($con, "UPDATE `".$table."` SET `reconfigured` = '1' WHERE `".$table."`.`id` = '".$_GET['id']."'");
}

$string1 = mysqli_query($con, "SELECT name FROM `".$table."` WHERE reconfigured = '0' LIMIT 1");
$string2 = mysqli_query($con2, "SELECT name FROM `".$table."` WHERE reconfigured = '0' LIMIT 1");
  $string1 = mysqli_fetch_row($con, $string1);
  $string2 = mysqli_fetch_row($con2, $string2);
  $string1 = $string1['0'];
  $string2 = $string2['0'];
?>


<form action="">

    <input type="text" id="id" name="id" value="<?= $id ?>"></input><br>
    
  <input type="radio" id="which" name="which" value="1"><?= $string1 ?><br>

  <input type="radio" id="which" name="which" value="2"><?= $string2 ?><br><br>
  
  <input type="submit" value="continue">

  </form>

我没有测试过这个脚本,谨慎使用并进行数据库备份

编辑,这种方式是自动的,如果它有一个损坏的单词(如 œ),它会用另一种方法更新它,我仔细检查了代码,但你也检查了一个数据库再次备份,我有点不相信自己

<?php

$broken = array('×', '¢', 'œ', 'ª');
$server = "localhost";
$username = "root";
$password = "";
$database = "database";

$table = "corrupted table";

//utf8
$con = mysqli_connect($server, $username, $password, $database);
mysqli_set_charset($con,"utf8");
//auto
$con2 = mysqli_connect($server, $username, $password, $database);
$fixed = 0;
while ($fixed == 1) {
$string1 = mysqli_query($con, "SELECT name FROM `".$table."` WHERE reconfigured = '0' LIMIT 1");
$string2 = mysqli_query($con2, "SELECT name FROM `".$table."` WHERE reconfigured = '0' LIMIT 1");
  $string1 = mysqli_fetch_row($con, $string1);
  $string2 = mysqli_fetch_row($con2, $string2);
  if(implode(null,$string1) == null){ die('done'); }
  if(implode(null,$string2) == null){ die('done'); }
  $string1 = $string1['0'];
  $string2 = $string2['0'];
  
while ($found == 1) { 
foreach ($broken as $badword) {
if(strpos($string1, $badword)) { $found = 1; $broken = 1; }
} 
$found = 1;
}
if ($broken == 1) {
  mysqli_query($con, "UPDATE `".$table."` SET `name` = '".$string2."' WHERE `".$table."`.`id` = '".$id."'");

  
  
}
  mysqli_query($con, "UPDATE `".$table."` SET `reconfigured` = '1' WHERE `".$table."`.`id` = '".$id."'");
unset($broken);
unset($found);
}
?>

【讨论】:

  • 我刚刚意识到也许我可以自动执行此操作,您可以从名称列中复制粘贴我无法读取的行吗?
  • 我做了类似的事情,对于每个表,我为安全性做了单独的文件,2 个数据库连接(1 个带有 utf8,另一个没有)并循环读取原始文件,然后使用 UTF8 连接更新 - 有效完美:) 谢谢!
  • INSERT INTO orders (id, products, price, qty, ordernu) VALUES (10, 'נצמד שלישיה ניילון 300/45 ML', '79', '3', 4), (3, 'תיק וועידה ממותג', '12', '500', 2); 应该如何:INSERT INTO orders (id, products, price, qty, ordernum) VALUES (10, 'נצמד שלישיה ניילון 300/45 ML', '79', '3', 4), (3, 'תיק וועידה ממותג', '12', '500', 2);
  • 我添加了自动方式,别忘了重新备份数据库
猜你喜欢
  • 2013-04-13
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多