Sebuah string PHP hanyalah urutan byte, tanpa pengkodean yang ditandai untuk itu. Nilai string dapat berasal dari berbagai sumber: klien (melalui HTTP), database, file, atau dari string literal dalam kode sumber Anda. PHP membaca semua ini sebagai urutan byte, dan tidak pernah mengekstrak informasi pengodean apa pun.
Selama semua sumber data dan tujuan Anda menggunakan penyandian yang sama, hal terburuk yang dapat terjadi adalah bahwa posisi string salah (jika Anda menggunakan penyandian multi-byte), karena PHP akan menghitung byte, bukan karakter.
Tetapi jika pengkodean tidak cocok (misalnya Anda menulis string literal dalam file sumber yang disimpan sebagai UTF-8, dan kemudian mengirimnya ke database yang mengharapkan Latin-1), PHP tidak akan melakukan konversi untuk Anda: itu akan dengan senang hati menyalin byte di atas mentah.
Solusi terbaik adalah ini:
- Atur pengodean internal PHP ke UTF-8.
- Simpan semua file sumber Anda sebagai UTF-8.
- Gunakan UTF-8 sebagai penyandian keluaran Anda (jangan lupa untuk mengirim
Content-type
tajuk yang sesuai ).
- Atur koneksi database untuk menggunakan UTF-8 (
SET NAMES UTF8
di MySQL).
- Konfigurasikan yang lainnya menjadi UTF-8 jika memungkinkan.
- Untuk apa pun yang tidak dapat Anda kontrol (mis. Layanan web pihak ketiga), pastikan Anda mengetahui penyandian, dan mengonversi ke UTF-8 sedini mungkin, dan kembali ke penyandian lain selambat mungkin.
Mengapa UTF-8? Karena itu dapat mewakili semua karakter Unicode dan dengan demikian menggantikan semua pengkodean 7-bit dan 8-bit yang ada, dan karena itu adalah biner yang kompatibel dengan ASCII, yaitu, setiap string ASCII yang valid juga merupakan string UTF-8 yang valid (tetapi tidak vv .).
Dalam contoh Anda, apa yang terjadi adalah ini.
Pertama, Anda menyimpan file sumber Anda; editor teks Anda mungkin dikonfigurasikan untuk menggunakan UTF-8, jadi string literal Anda berakhir dengan UTF-8 yang disandikan pada disk. PHP membaca file ini, menafsirkan string sebagai serangkaian byte; $original
sekarang memegang string yang dikodekan UTF-8 dengan 7 karakter, yang hanya merupakan urutan byte (meskipun berisi lebih dari 7 byte, karena setiap karakter diwakili oleh dua atau lebih byte). Jika Anda menelepon echo $original
, string yang disandikan dikirim ke klien apa adanya; jika Anda telah memberitahu klien untuk mengharapkan UTF-8, semuanya baik-baik saja, tetapi jika Anda belum, PHP tidak memiliki cara untuk membedakannya, dan Anda akan berakhir dengan sampah di browser. Sebagai percobaan, coba ini:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
adalah pengkodean-agnostik dan mengasumsikan pengodean 8 bit dengan lebar tetap, yaitu, satu byte per karakter, sehingga akan menghitung byte, bukan karakter.