it-swarm-id.com

Karakter Aneh dalam teks basis data: Ã, Ã, ¢, â ‚€,

Saya tidak yakin kapan ini pertama kali terjadi.

Saya memiliki situs web afiliasi pengiriman drop-baru, dan menerima salinan katalog produk yang diekspor dari grosir. Saya memformat dan mengimpor ini ke Prestashop 1.4.4.

Ujung depan situs web berisi kombinasi karakter aneh di dalam teks produk: Ã, Ã, ¢, â ‚dll. Mereka muncul sebagai ganti karakter umum seperti, -: dll.

Karakter-karakter ini hadir di sekitar 40% dari tabel database, bukan hanya tabel spesifik produk seperti ps_product_lang.

tas situs web lain mengatakan masalah yang sama ini terjadi ketika string koneksi database menggunakan jenis pengkodean karakter yang salah .

Di /config/setting.inc, tidak ada string pengkodean karakter yang disebutkan, hanya Mesin MySQL, yang diatur ke InnoDB, yang cocok dengan apa yang saya lihat di PHPMyAdmin.

Saya mengekspor ps_product_lang, mengganti semua instance dari karakter-karakter ini dengan karakter yang benar, menyimpan file CSV dalam format UTF-8, dan mengimpornya kembali menggunakan PHPMyAdmin, menetapkan UTF-8 sebagai bahasa.

Namun, setelah melakukan pencarian baru di PHPMyAdmin, saya sekarang memiliki sekitar 10 kali lebih banyak contoh dari karakter buruk ini di ps_product_lang daripada yang saya mulai.

Jika masalahnya sesederhana seperti menentukan atribut bahasa yang benar dalam string koneksi database, di mana/bagaimana cara mengatur ini, dan apa yang harus dilakukan?

Kebetulan, saya mencoba menjalankan perintah ini di PHPMyAdmin yang disebutkan dalam tas ini , tetapi masalahnya tetap:

SET NAMES utf8

[~ # ~] pembaruan [~ # ~] : PHPMyAdmin mengatakan:

MySQL charset: UTF-8 Unicode (utf8)

Ini adalah set karakter yang sama yang saya gunakan dalam file impor terakhir, yang menyebabkan lebih banyak karakter yang rusak. UTF-8 ditetapkan sebagai charset dari file impor selama proses impor.

UPDATE2

Berikut ini contohnya:

orang-orang benar-benar hidup tanpa ikatan ¢ à¢ à ¢ €šÂ¬Â¯à ¢ â¢¬Â Ã‚ï † membeli dan menyewa film secara online, mengunduh perangkat lunak, dan berbagi serta menyimpan file di Web.

UPDATE3

Saya menjalankan perintah SQL di PHPMyAdmin untuk menampilkan set karakter:

  • character_set_client utf8
  • character_set_connection utf8
  • character_set_database latin1
  • biner character_set_filesystem
  • karakter_set_hasil utf8
  • character_set_server latin1
  • character_set_system utf8

Jadi, mungkin basis data saya perlu dikonversi (atau dihapus dan diciptakan kembali) ke UTF-8. Bisakah ini menimbulkan masalah jika server MySQL latin1?

Dapatkah MySQL menangani terjemahan konten penyajian sebagai UTF8 tetapi menyimpannya sebagai latin1? Saya tidak berpikir itu bisa, karena UTF8 adalah superset dari latin1. Dukungan hosting web saya belum menjawab dalam 48 jam. Mungkin terlalu sulit bagi mereka.

25
Steve

Jika rangkaian tabel sama dengan isinya, coba gunakan mysql_set_charset('UTF8', $link_identifier) . Perhatikan bahwa MySQL menggunakan UTF8 untuk menentukan pengkodean UTF-8 alih-alih UTF-8 yang lebih umum.

Periksa jawaban saya yang lain pada pertanyaan serupa juga.

17
AlexV

Ini jelas merupakan masalah penyandian. Anda memiliki penyandian berbeda di database Anda dan di situs web Anda dan fakta ini adalah penyebab masalahnya. Juga jika Anda menjalankan perintah itu, Anda harus mengubah catatan yang sudah ada di tabel Anda untuk mengonversi karakter tersebut di UTF-8.

Pembaruan : Berdasarkan komentar terakhir Anda, inti masalahnya adalah bahwa Anda memiliki database dan sumber data (file CSV) yang menggunakan pengodean berbeda . Oleh karena itu Anda dapat mengonversi basis data Anda dalam UTF-8 atau, setidaknya, ketika Anda mendapatkan data yang ada di CSV, Anda harus mengonversinya dari UTF-8 ke latin1.

Anda dapat melakukan konversi dengan mengikuti artikel ini:

5
Aurelio De Rosa

Terapkan dua hal ini.

  1. Anda perlu mengatur rangkaian karakter basis data Anda menjadi utf8.

  2. Anda perlu memanggil mysql_set_charset('utf8') dalam file tempat Anda membuat koneksi dengan database dan segera setelah pemilihan database seperti mysql_select_db Gunakan mysql_set_charset. Itu akan memungkinkan Anda untuk menambah dan mengambil data dengan benar dalam bahasa apa pun.

2
Haisum Usman

Ini tampaknya menjadi masalah pengkodean UTF-8 yang mungkin disebabkan oleh pengkodean ganda file konten basis data UTF8.

Situasi ini dapat terjadi karena faktor-faktor seperti set karakter yang dipilih atau tidak dipilih (misalnya ketika file cadangan database dibuat) dan format file serta penyandian file database disimpan.

Saya telah melihat karakter-karakter UTF-8 yang aneh ini dalam skenario berikut (deskripsi mungkin tidak sepenuhnya akurat karena saya tidak lagi memiliki akses ke database yang dimaksud):

  • Seingat saya, di sana basis data dan tabel memiliki susunan "uft8_general_ci".
  • Cadangan dibuat dari basis data.
  • File cadangan dibuka pada Windows dalam format file UNIX dan dengan penyandian ANSI.
  • Database dipulihkan pada server MySQL baru dengan menyalin-menempelkan konten dari file cadangan database ke phpMyAdmin.

Melihat isi file:

  • Membuka file cadangan SQL dalam editor teks menunjukkan bahwa file cadangan SQL memiliki karakter aneh seperti "sà¥". Di samping catatan, Anda mungkin mendapatkan hasil yang berbeda jika membuka file yang sama di editor lain. Saya menggunakan TextPad di sini tetapi membuka file yang sama di SublimeText berkata "sà ¥" karena SublimeText dengan benar menyandikan file UTF8 - masih, ini agak membingungkan ketika Anda mulai mencoba untuk memperbaiki masalah di PHP karena Anda tidak dapat melihat data yang tepat di SublimeText pada awalnya. Bagaimanapun, itu dapat diatasi dengan mencatat pengkodean yang digunakan editor teks Anda saat menyajikan konten file.
  • Karakter aneh adalah karakter UTF-8 berkode ganda, jadi dalam kasus saya bagian "Ã" pertama sama dengan "Ã" dan " ¥" = "¥" (ini adalah "pengkodean" pertama saya). Karakter "à ¥" sama dengan karakter UTF-8 untuk "å" (ini adalah pengkodean kedua saya).

Jadi, masalahnya adalah "false" (dikodekan UTF8 dua kali) utf-8 perlu dikonversi kembali menjadi "benar" utf-8 (hanya dikodekan UTF8 satu kali).

Mencoba untuk memperbaikinya di PHP ternyata sedikit menantang:

utf8_decode () tidak dapat memproses karakter.

// Fails silently (as in - nothing is output)
$str = "så";

$str = utf8_decode($str);
printf("\n%s", $str);

$str = utf8_decode($str);
printf("\n%s", $str);

iconv () gagal dengan "Pemberitahuan: iconv (): Terdeteksi karakter ilegal di string input".

echo iconv("UTF-8", "ISO-8859-1", "så");

Lain solusi baik dan mungkin gagal diam-diam juga dalam skenario ini

$str = "så";
echo html_entity_decode(htmlentities($str, ENT_QUOTES, 'UTF-8'), ENT_QUOTES , 'ISO-8859-15');

mb_convert_encoding () secara diam-diam: #

$str = "så";
echo mb_convert_encoding($str, 'ISO-8859-15', 'UTF-8');
// (No output)

Mencoba memperbaiki pengkodean di MySQL dengan mengubah karakter dan susunan basis data MySQL ke UTF-8 tidak berhasil:

ALTER DATABASE myDatabase CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE myTable CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Saya melihat beberapa cara untuk mengatasi masalah ini.

Yang pertama adalah membuat cadangan dengan pengkodean yang benar (pengkodean harus sesuai dengan database aktual dan pengkodean tabel). Anda dapat memverifikasi pengkodean dengan hanya membuka file SQL yang dihasilkan dalam editor teks.

Yang lain adalah mengganti karakter berkode ganda UTF8 dengan karakter tunggal berkode UTF8. Ini dapat dilakukan secara manual dalam editor teks. Untuk membantu dalam proses ini, Anda dapat secara manual memilih karakter yang salah dari Coba TF-8 Encoding Debugging Chart (ini mungkin masalah mengganti 5-10 kesalahan).

Akhirnya, sebuah skrip dapat membantu dalam proses:

    $str = "så";
    // The two arrays can also be generated by double-encoding values in the first array and single-encoding values in the second array.
    $str = str_replace(["Ã","Â¥"], ["Ã","¥"], $str); 
    $str = utf8_decode($str);
    echo $str;
    // Output: "så" (correct)
2

Saya mengalami masalah yang hampir sama hari ini: mysqldump membuang utf-8 base encoding utf-8 karakter diakritik sebagai dua karakter latin1, meskipun file itu sendiri adalah utf8 biasa.

Misalnya: "é" dikodekan sebagai dua karakter "Ã ©". Dua karakter ini sesuai dengan utf8 dua byte pengkodean huruf tetapi harus ditafsirkan sebagai karakter tunggal.

Untuk mengatasi masalah dan mengimpor database dengan benar di server lain, saya harus mengonversi file menggunakan ftfy (singkatan dari "Fixes Text For You). ( https://github.com/LuminosoInsight/python-ftfy) ) python pustaka. Pustaka melakukan tepat seperti yang saya harapkan: mentransformasikan utf-8 yang disandikan dengan buruk agar benar-benar disandikan di-utf-8.

Misalnya: Kombinasi latin1 "Ã ©" ini berubah menjadi "é".

ftfy datang dengan skrip baris perintah tetapi mengubah file sehingga tidak dapat diimpor kembali ke mysql.

Saya menulis skrip python3 untuk melakukan trik:

#!/usr/bin/python3
# coding: utf-8

import ftfy

# Set input_file
input_file = open('mysql.utf8.bad.dump', 'r', encoding="utf-8")
# Set output file
output_file = open ('mysql.utf8.good.dump', 'w')

# Create fixed output stream
stream = ftfy.fix_file(
    input_file,
    encoding=None,
    fix_entities='auto', 
    remove_terminal_escapes=False, 
    fix_encoding=True, 
    fix_latin_ligatures=False, 
    fix_character_width=False, 
    uncurl_quotes=False, 
    fix_line_breaks=False, 
    fix_surrogates=False, 
    remove_control_chars=False, 
    remove_bom=False, 
    normalization='NFC'
)

# Save stream to output file
stream_iterator = iter(stream)
while stream_iterator:
    try:
        line = next(stream_iterator)
        output_file.write(line)
    except StopIteration:
        break
1
Pielo

Kesalahan biasanya diperkenalkan saat pembuatan CSV. Coba gunakan Linux untuk menyimpan CSV sebagai TextCSV. Libre Office di Ubuntu dapat menerapkan pengkodean menjadi UTF-8, bekerja untuk saya. Saya membuang banyak waktu untuk mencoba ini di Mac OS. Linux adalah kuncinya. Saya sudah menguji di Ubuntu.

Semoga berhasil

1
Achin Kumar