Saya membacakan banyak teks dari berbagai umpan RSS dan memasukkannya ke dalam basis data saya.
Tentu saja, ada beberapa pengkodean karakter yang berbeda yang digunakan dalam umpan, misalnya UTF-8 dan ISO 8859-1.
Sayangnya, terkadang ada masalah dengan penyandian teks. Contoh:
"Ss" di "Fußball" akan terlihat seperti ini di basis data saya: "Ÿ". Jika "Ÿ", itu ditampilkan dengan benar.
Terkadang, "ß" di "Fußball" terlihat seperti ini di basis data saya: "ß". Maka itu ditampilkan salah, tentu saja.
Dalam kasus lain, "ß" disimpan sebagai "ß" - jadi tanpa perubahan apa pun. Maka itu juga ditampilkan salah.
Apa yang bisa saya lakukan untuk menghindari kasus 2 dan 3?
Bagaimana saya bisa membuat semuanya pengkodean yang sama, sebaiknya UTF-8? Kapan saya harus menggunakan utf8_encode()
, kapan saya harus menggunakan utf8_decode()
(jelas apa efeknya tetapi kapan saya harus menggunakan fungsi?) Dan kapan saya tidak melakukan apa-apa dengan input?
Bagaimana cara membuat semuanya menjadi sama? Mungkin dengan fungsinya mb_detect_encoding()
? Bisakah saya menulis fungsi untuk ini? Jadi masalah saya adalah:
- Bagaimana cara mengetahui pengkodean yang digunakan teks?
- Bagaimana cara mengonversinya menjadi UTF-8 - apa pun pengkodean lama itu?
Apakah fungsi seperti ini berfungsi?
function correct_encoding($text) {
$current_encoding = mb_detect_encoding($text, 'auto');
$text = iconv($current_encoding, 'UTF-8', $text);
return $text;
}
Saya sudah mengujinya, tetapi tidak berhasil. Apakah ada yang salah?
Jawaban:
Jika Anda menerapkan
utf8_encode()
string UTF-8 yang sudah ada, itu akan mengembalikan output UTF-8 yang kacau.Saya membuat fungsi yang mengatasi semua masalah ini. Itu disebut
Encoding::toUTF8()
.Anda tidak perlu tahu apa penyandian string Anda. Ini bisa berupa Latin1 ( ISO 8859-1) , Windows-1252 atau UTF-8, atau string dapat memiliki campuran dari mereka.
Encoding::toUTF8()
akan mengonversi semuanya menjadi UTF-8.Saya melakukannya karena sebuah layanan memberi saya data yang semua kacau, mencampur UTF-8 dan Latin1 dalam string yang sama.
Pemakaian:
Unduh:
https://github.com/neitanod/forceutf8
Saya telah menyertakan fungsi lain
Encoding::fixUFT8()
, yang akan memperbaiki setiap string UTF-8 yang terlihat kacau.Pemakaian:
Contoh:
akan menampilkan:
Saya telah mengubah fungsi (
forceUTF8
) menjadi keluarga fungsi statis pada kelas yang disebutEncoding
. Fungsi baru adalahEncoding::toUTF8()
.sumber
Anda harus terlebih dahulu mendeteksi encoding apa yang telah digunakan. Saat Anda mem-parsing umpan RSS (mungkin melalui HTTP), Anda harus membaca pengkodean dari
charset
parameterContent-Type
bidang header HTTP . Jika tidak ada, baca pengodean dariencoding
atribut instruksi pemrosesan XML . Jika itu juga hilang, gunakan UTF-8 seperti yang ditentukan dalam spesifikasi .Sunting Inilah yang mungkin akan saya lakukan:
Saya akan menggunakan cURL untuk mengirim dan mengambil respons. Itu memungkinkan Anda untuk mengatur bidang tajuk spesifik dan mengambil tajuk respons juga. Setelah mengambil respons, Anda harus menguraikan respons HTTP dan membaginya menjadi header dan badan. Header kemudian harus berisi
Content-Type
bidang header yang berisi tipe MIME dan (mudah-mudahan)charset
parameter dengan pengkodean / charset juga. Jika tidak, kami akan menganalisis PI XML untuk keberadaanencoding
atribut dan mendapatkan pengkodean dari sana. Jika itu juga tidak ada, spesifikasi XML menentukan untuk menggunakan UTF-8 sebagai pengkodean.sumber
charset=
danencoding=
dan tidak hanya pada posisi yang tepat. Dan ketiga, Anda tidak memeriksa apakah pengkodean yang dinyatakan diterima.Mendeteksi encoding itu sulit.
mb_detect_encoding
bekerja dengan menebak, berdasarkan sejumlah kandidat yang Anda lewati. Dalam beberapa pengkodean, urutan byte tertentu tidak valid, dan karenanya dapat membedakan berbagai kandidat. Sayangnya, ada banyak pengkodean, di mana byte yang sama valid (tetapi berbeda). Dalam kasus ini, tidak ada cara untuk menentukan pengkodean; Anda dapat menerapkan logika Anda sendiri untuk membuat tebakan dalam kasus-kasus ini. Misalnya, data yang berasal dari situs Jepang mungkin lebih cenderung memiliki penyandian Jepang.Selama Anda hanya berurusan dengan bahasa Eropa Barat, tiga penyandian utama untuk dipertimbangkan adalah
utf-8
,iso-8859-1
dancp-1252
. Karena ini adalah default untuk banyak platform, mereka juga kemungkinan besar dilaporkan salah. Misalnya. jika orang menggunakan pengkodean yang berbeda, mereka cenderung jujur tentang hal itu, karena perangkat lunak mereka akan sangat sering rusak. Oleh karena itu, strategi yang baik adalah mempercayai penyedia, kecuali jika pengkodean dilaporkan sebagai salah satu dari ketiganya. Anda masih harus memeriksa dua kali bahwa itu memang benar, menggunakanmb_check_encoding
(perhatikan bahwa valid tidak sama dengan menjadi - input yang sama mungkin berlaku untuk banyak pengkodean). Jika itu salah satunya, Anda bisa menggunakannyamb_detect_encoding
untuk membedakan di antara mereka. Untungnya itu cukup deterministik; Anda hanya perlu menggunakan urutan deteksi yang tepat, yaituUTF-8,ISO-8859-1,WINDOWS-1252
.Setelah Anda mendeteksi pengkodean, Anda perlu mengubahnya ke representasi internal Anda (
UTF-8
adalah satu-satunya pilihan yang waras). Fungsiutf8_encode
berubahISO-8859-1
menjadiUTF-8
, jadi hanya bisa digunakan untuk tipe input tertentu. Untuk penyandian lainnya, gunakanmb_convert_encoding
.sumber
Cara yang sangat bagus untuk mengimplementasikan
isUTF8
-fungsi dapat ditemukan di php.net :sumber
mb_check_encoding($string, 'UTF-8')
Cheatsheet ini berisi daftar beberapa peringatan umum terkait penanganan UTF-8 di PHP: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet
Fungsi ini mendeteksi karakter multibyte dalam sebuah string mungkin juga bermanfaat ( sumber ):
sumber
Sedikit kepala. Anda mengatakan bahwa "ß" harus ditampilkan sebagai "Ÿ" di database Anda.
Ini mungkin karena Anda menggunakan database dengan pengkodean karakter Latin-1 atau mungkin koneksi PHP-MySQL Anda salah, ini, P, percaya MySQL Anda diatur untuk menggunakan UTF-8, sehingga mengirimkan data sebagai UTF-8 , tetapi MySQL Anda yakin PHP mengirim data yang disandikan sebagai ISO 8859-1, jadi mungkin sekali lagi mencoba untuk menyandikan data terkirim Anda sebagai UTF-8, yang menyebabkan masalah seperti ini.
Lihatlah mysql_set_charset . Ini dapat membantu Anda.
sumber
Pengkodean Anda sepertinya dikodekan ke dalam UTF-8 dua kali ; yaitu, dari beberapa pengkodean lainnya, ke UTF-8, dan lagi ke UTF-8. Seolah-olah Anda memiliki ISO 8859-1, dikonversi dari ISO 8859-1 ke UTF-8, dan memperlakukan string baru sebagai ISO 8859-1 untuk konversi lain menjadi UTF-8.
Inilah beberapa kodesemu dari apa yang Anda lakukan:
Kamu harus mencobanya:
mb_detect_encoding()
atau apa pun yang Anda suka gunakanItu mengasumsikan bahwa dalam konversi "tengah" Anda menggunakan ISO 8859-1. Jika Anda menggunakan Windows-1252, kemudian konversikan ke Windows-1252 (latin1). Pengkodean sumber asli tidak penting; yang Anda gunakan dalam cacat, konversi kedua adalah.
Ini dugaan saya tentang apa yang terjadi; ada sangat sedikit lagi yang bisa Anda lakukan untuk mendapatkan empat byte sebagai pengganti satu byte ASCII yang diperluas.
Bahasa Jerman juga menggunakan ISO 8859-2 dan Windows-1250 (Latin-2).
sumber
Hal yang menarik tentang
mb_detect_encoding
danmb_convert_encoding
adalah bahwa urutan pengkodean yang Anda sarankan itu penting:Jadi, Anda mungkin ingin menggunakan perintah tertentu saat menentukan pengkodean yang diharapkan. Namun, perlu diingat bahwa ini tidak mudah.
sumber
if ($input_is_not_UTF8) $input_is_windows1252 = true;
. Lihat juga: html.spec.whatwg.org/multipage/…Anda perlu menguji set karakter pada input karena tanggapan dapat dikodekan dengan pengkodean yang berbeda.
Saya memaksa semua konten dikirim ke UTF-8 dengan melakukan deteksi dan terjemahan menggunakan fungsi berikut:
Rutin itu akan mengubah semua variabel PHP yang berasal dari remote host menjadi UTF-8.
Atau abaikan nilainya jika pengkodean tidak dapat dideteksi atau dikonversi.
Anda dapat menyesuaikannya dengan kebutuhan Anda.
Hanya memohonnya sebelum menggunakan variabel.
sumber
Mengerjakan pengkodean karakter dari umpan RSS tampaknya rumit . Bahkan halaman web biasa sering menghilangkan, atau berbohong tentang, pengkodeannya.
Jadi Anda bisa mencoba menggunakan cara yang benar untuk mendeteksi pengkodean dan kemudian kembali ke beberapa bentuk deteksi otomatis (menebak).
sumber
charset
/encoding
deklarasi jika untuk: menggambarkan pengkodean data dikodekan.Saya tahu ini adalah pertanyaan yang lebih tua, tetapi saya pikir jawaban yang bermanfaat tidak pernah sakit. Saya mengalami masalah dengan pengkodean antara aplikasi desktop, SQLite, dan variabel GET / POST. Beberapa di UTF-8, beberapa di ASCII, dan pada dasarnya semuanya akan kacau ketika karakter asing terlibat.
Ini solusinya. Itu menggosok GET / POST / REQUEST Anda (saya hilangkan cookie, tetapi Anda bisa menambahkannya jika diinginkan) pada setiap halaman dimuat sebelum diproses. Ini berfungsi dengan baik di header. PHP akan memberikan peringatan jika tidak dapat mendeteksi pengkodean sumber secara otomatis, sehingga peringatan ini ditekan dengan @ 's.
sumber
Saya memeriksa solusi untuk penyandian sejak lama , dan halaman ini mungkin merupakan kesimpulan dari pencarian bertahun-tahun! Saya menguji beberapa saran yang Anda sebutkan dan inilah catatan saya:
Ini adalah string pengujian saya:
Saya melakukan INSERT untuk menyimpan string ini pada database di bidang yang ditetapkan sebagai
utf8_general_ci
Set karakter halaman saya adalah UTF-8.
Jika saya melakukan INSERT seperti itu, di basis data saya, saya mungkin memiliki beberapa karakter yang berasal dari Mars ...
Jadi saya perlu mengubahnya menjadi "waras" UTF-8. Saya mencoba
utf8_encode()
, tetapi masih ada alien yang menyerang basis data saya ...Jadi saya mencoba menggunakan fungsi yang
forceUTF8
diposting pada nomor 8, tetapi dalam database string yang disimpan terlihat seperti ini:Jadi mengumpulkan beberapa informasi lebih lanjut di halaman ini dan menggabungkannya dengan informasi lain di halaman lain, saya memecahkan masalah saya dengan solusi ini:
Sekarang dalam database saya, saya memiliki string dengan pengkodean yang benar.
CATATAN: Hanya catatan yang harus diperhatikan yang berfungsi
mysql_client_encoding
! Anda harus terhubung ke database, karena fungsi ini menginginkan ID sumber daya sebagai parameter.Tapi yah, saya hanya melakukan pengkodean ulang sebelum INSERT saya jadi bagi saya itu bukan masalah.
sumber
UTF-8
pengkodean klien untuk mysql? Tidak perlu konversi manual dengan cara iniItu sederhana: ketika Anda mendapatkan sesuatu yang tidak UTF-8, Anda harus menyandikan bahwa dalam UTF-8.
Jadi, saat Anda mengambil feed tertentu, ISO 8859-1 menguraikannya
utf8_encode
.Namun, jika Anda mengambil umpan UTF-8, Anda tidak perlu melakukan apa pun.
sumber
php.net/
mb_detect_encoding
atau
saya benar-benar tidak tahu apa hasilnya, tetapi saya sarankan Anda hanya mengambil beberapa feed Anda dengan pengkodean yang berbeda dan coba apakah
mb_detect_encoding
berfungsi atau tidak.pembaruan
otomatis adalah kependekan dari "ASCII, JIS, UTF-8, EUC-JP, SJIS". ia mengembalikan charset yang terdeteksi, yang dapat Anda gunakan untuk mengonversi string menjadi utf-8 dengan iconv .
saya belum mengujinya, jadi tidak ada jaminan. dan mungkin ada cara yang lebih sederhana.
sumber
@ Harpax yang bekerja untuk saya. Dalam kasus saya, ini cukup bagus:
sumber
Setelah memilah skrip php Anda, jangan lupa memberi tahu mysql charset apa yang Anda lewati dan ingin menerima.
Contoh: set karakter set utf8
Melewati data utf8 ke tabel latin1 dalam sesi latin1 I / O memberikan mereka birdfeet jahat. Saya melihat ini setiap hari di toko-toko oscommerce. Kembali dan keempat sepertinya benar. Tapi phpmyadmin akan menunjukkan kebenaran. Dengan memberi tahu mysql charset apa yang Anda lewati, ia akan menangani konversi data mysql untuk Anda.
Bagaimana memulihkan data mysql teracak yang ada adalah utas lain untuk didiskusikan. :)
sumber
Versi ini untuk bahasa Jerman tetapi Anda dapat memodifikasi $ CHARSETS dan $ TESTCHARS
sumber
Dapatkan encoding dari header dan konversikan ke utf-8.
sumber
Ÿ
adalah untuk Mojibakeß
. Di database Anda, Anda mungkin memiliki hexAnda tidak boleh menggunakan fungsi encoding / decoding dalam PHP; alih-alih, Anda harus mengatur basis data dan koneksi dengan benar.
Jika MySQL terlibat, lihat: Masalah dengan karakter utf8; apa yang saya lihat bukan apa yang saya simpan
sumber
Saya menemukan solusi di sini http://deer.org.ua/2009/10/06/1/
Saya pikir @ adalah keputusan yang buruk, dan membuat beberapa perubahan pada solusi dari deer.org.ua;
sumber
Jawaban yang paling banyak dipilih tidak berfungsi. Ini milik saya dan saya harap ini membantu.
sumber
Ketika Anda mencoba menangani multi bahasa seperti Jepang dan Korea, Anda mungkin akan mendapat masalah. mb_convert_encoding dengan parameter 'otomatis' tidak berfungsi dengan baik. Pengaturan mb_detect_order ('ASCII, UTF-8, JIS, EUC-JP, SJIS, EUC-KR, UHC') tidak membantu karena akan mendeteksi EUC- * salah.
Saya menyimpulkan bahwa selama string input berasal dari HTML, harus menggunakan 'charset' dalam elemen meta. Saya menggunakan Parser DOM HTML Sederhana karena mendukung HTML yang tidak valid.
Cuplikan di bawah ini mengekstrak elemen judul dari halaman web. Jika Anda ingin mengonversi seluruh halaman, maka Anda mungkin ingin menghapus beberapa baris.
sumber
Saya memiliki masalah yang sama dengan phpQuery ( ISO-8859-1 bukannya UTF-8 ) dan peretasan ini membantu saya:
mb_internal_encoding('UTF-8')
,phpQuery::newDocumentHTML($html, 'utf-8')
,mbstring.internal_encoding
Dan manipulasi lainnya tidak mengambil efek apapun.sumber
Coba tanpa 'otomatis'
Itu adalah:
dari pada:
Informasi lebih lanjut dapat ditemukan di sini: mb_detect_encoding
sumber