【问题标题】:PHP: remove special characters like � while importing data from CSV to database [duplicate]PHP:在将数据从 CSV 导入数据库时​​删除特殊字符,如 �
【发布时间】:2017-08-03 07:35:20
【问题描述】:

我创建了一个 PHP 脚本,允许我从 csv 文件上传一个巨大的数据文件。导入时,我想将 等特殊字符替换为字母 c。以下是我的代码:

        $sql ="INSERT INTO bill_of_materials(allotment_code, category_name, activity, quantity, end_unit_quantity, unit, description,
        unit_cost, regular_labor_cost, end_unit_labor_cost, type, batch) VALUES";

        while (($line = fgets($handle)) !== false) {

          $sql .= "('".implode("', '", explode(";", sanitize($line)))."'),";
          $counter++;
        }

            $sql = substr($sql, 0, strlen($sql) - 1);
             if (mysqli_query($new_conn, $sql) === TRUE) {

                echo 1;

                //database file name
                $new_database_file = $new_database.'.sql';

                if(file_exists('backup/'.$new_database_file)) {

                    unlink('backup/'.$new_database_file);

                    // backup main database

                    $command = "C:/xampp/mysql/bin/mysqldump --host=$host --user=$user --password=$pass $database_name > backup/$new_database_file";
                    system($command);

                } else {
                    // backup main database

                    $command = "C:/xampp/mysql/bin/mysqldump --host=$host --user=$user --password=$pass $database_name > backup/$new_database_file";
                    system($command);
                }
            } else {
                echo $sql;
            }

此外,我的 CSV 中有一个数据是 W2-A1 2/F Front Fa�ade - B,我希望看到类似 W2-A1 的输出2/F 正面 - B。我该怎么做?

【问题讨论】:

标签: php csv str-replace


【解决方案1】:

首先,确保您使用的是正确的database client charset collation。 如果数据库字符集/排序规则正确,您可以使用preg_replace 来清理脏字符,如下所示:

function sanitize($line){
   $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $line); // attempt to translate similar characters
   $clean = preg_replace('/[^\w]/', '', $clean); // drop anything but ASCII
   return $clean;
}

如果这没有帮助(例如,您确实损坏了二进制流 - 例如从旧 Excel 源文件保存到 CSV),您可能想要使用二进制翻译字符(首先您必须找出损坏的二进制序列,例如通过转储它通过chr(ord($line[$position]))) - 示例:

function sanitize($line){
    $map = [
        // corrupted chars sequence -> fixed chars
        "\xC3\xA8" => 'č',
        "\xC3\x88" => 'Č',
        "\xC3\xB9" => 'ů',
        "\xC3\x99" => 'Ů',
        "\xC3\xAC" => 'ě',
        "\xC3\x8C" => 'Ě',
        "\xC3\xB8" => 'ř',
        "\xC3\x98" => 'Ř',
        "\x53\xC2\x8D" => 'Š',
        "\xC2\xA9" => 'Š',
    ];
    return str_replace(array_keys($map), $map, $line);
}

【讨论】:

  • 这对我有用。谢谢。
  • 这不是一个好的解决方案。修复核心问题,而不是修补它。如果您将整个代码管道设置为正确的字符集,那将正确解决您的问题。 “损坏”一词在这种情况下也不正确,它只是一种不同的编码。
  • @Qirel 请注意,第一句话建议修复数据库客户端排序规则/字符集。建议的 PHP 函数是用户无法修复的后备解决方案。
  • 修复字符集问题将防止进一步的编码问题,这种方法仍然会破坏任何新数据的编码。对于已经具有错误字符集的数据,这可能是一种解决方法 - 但不应替代对新数据条目的正确修复。
  • @Qirel 这个问题没有说明源 CSV 文件是否损坏。这是你自己的假设。如果例如,它可能会真正损坏。从使用 windows-1250 编码的旧 Excel 2003 文件保存为 UTF-8。我最近遇到了这种情况——我的任务是从第三方导入数百个旧的 CSV 文件,而许多文件的编码已损坏,无法获取固定的旧文件。二进制字符翻译是修复它的唯一方法。因此,设置正确的数据库客户端连接字符集可能会也可能不会解决问题。
猜你喜欢
  • 2013-02-05
  • 2019-08-03
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 2015-05-06
  • 2016-12-27
  • 2014-05-15
相关资源
最近更新 更多