Ada beberapa jawaban dan upaya yang sangat bagus untuk menjawab pertanyaan Anda di sini. Saya bukan master encoding, tapi saya mengerti keinginan Anda untuk memiliki setumpuk UTF-8 murni sampai ke database Anda. Saya telah menggunakan utf8mb4
pengkodean MySQL untuk tabel, bidang, dan koneksi.
Situasi saya berubah menjadi "Saya hanya ingin pembersih saya, validator, logika bisnis, dan menyiapkan pernyataan untuk berurusan dengan UTF-8 ketika data berasal dari formulir HTML, atau tautan pendaftaran email." Jadi, dengan cara sederhana saya, saya mulai dengan ide ini:
- Mencoba mendeteksi pengodean:
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
- Jika penyandian tidak dapat dideteksi,
throw new RuntimeException
- Jika input
UTF-8
, lanjutkan.
Lain, jika itu ISO-8859-1
atauASCII
Sebuah. Coba konversi ke UTF-8 (tunggu, belum selesai)
b. Mendeteksi penyandian nilai yang dikonversi
c. Jika pengkodean yang dilaporkan dan nilai yang dikonversi keduanya UTF-8
, lanjutkan.
d. Lain,throw new RuntimeException
Dari kelas abstrak saya Sanitizer
private function isUTF8($encoding, $value)
{
return (($encoding === 'UTF-8') && (utf8_encode(utf8_decode($value)) === $value));
}
private function utf8tify(&$value)
{
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
mb_internal_encoding('UTF-8');
mb_substitute_character(0xfffd); //REPLACEMENT CHARACTER
mb_detect_order($encodings);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if (!$stringEncoding) {
$value = null;
throw new \RuntimeException("Unable to identify character encoding in sanitizer.");
}
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = mb_convert_encoding($value, 'UTF-8', $stringEncoding);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = null;
throw new \RuntimeException("Unable to convert character encoding from ISO-8859-1, or ASCII, to UTF-8 in Sanitizer.");
}
}
return;
}
Orang bisa membuat argumen bahwa saya harus memisahkan masalah pengkodean dari Sanitizer
kelas abstrak saya dan cukup menyuntikkan Encoder
objek ke turunan anak konkret Sanitizer
. Namun, masalah utama dengan pendekatan saya adalah bahwa, tanpa lebih banyak pengetahuan, saya hanya menolak jenis penyandian yang tidak saya inginkan (dan saya mengandalkan fungsi PHP mb_ *). Tanpa studi lebih lanjut, saya tidak bisa tahu apakah itu menyakitkan sebagian populasi atau tidak (atau, jika saya kehilangan informasi penting). Jadi, saya perlu belajar lebih banyak. Saya menemukan artikel ini.
Apa yang mutlak perlu diketahui oleh setiap programmer, tentang penyandian dan rangkaian karakter untuk bekerja dengan teks
Selain itu, apa yang terjadi ketika data terenkripsi ditambahkan ke tautan pendaftaran email saya (menggunakan OpenSSL
atau mcrypt
)? Mungkinkah ini mengganggu decoding? Bagaimana dengan Windows-1252? Bagaimana dengan implikasi keamanan? Penggunaan utf8_decode()
dan utf8_encode()
dalam Sanitizer::isUTF8
meragukan.
Orang-orang telah menunjukkan kekurangan dalam fungsi PHP mb_ *. Saya tidak pernah meluangkan waktu untuk menyelidiki iconv
, tetapi jika berfungsi lebih baik daripada fungsi mb_ *, beri tahu saya.