สตริง PHP เป็นเพียงลำดับของไบต์โดยไม่มีการเข้ารหัสแท็กใด ๆ ค่าสตริงอาจมาจากแหล่งต่าง ๆ : ไคลเอนต์ (ผ่าน HTTP), ฐานข้อมูล, ไฟล์หรือจากตัวอักษรสตริงในซอร์สโค้ดของคุณ PHP อ่านสิ่งเหล่านี้ทั้งหมดเป็นลำดับไบต์และจะไม่แยกข้อมูลการเข้ารหัสใด ๆ
ตราบใดที่แหล่งข้อมูลและปลายทางของคุณใช้การเข้ารหัสแบบเดียวกันสิ่งที่แย่ที่สุดที่สามารถเกิดขึ้นได้คือตำแหน่งสตริงนั้นผิด (ถ้าคุณใช้การเข้ารหัสแบบหลายไบต์) เนื่องจาก PHP จะนับไบต์ไม่ใช่ตัวอักษร
แต่ถ้าการเข้ารหัสไม่ตรงกัน (เช่นคุณเขียนตัวอักษรสตริงในไฟล์ต้นฉบับที่เก็บเป็น UTF-8 แล้วส่งไปยังฐานข้อมูลที่คาดว่าละติน -1), PHP จะไม่ทำการแปลงใด ๆ สำหรับคุณ: มันจะ คัดลอกไบต์มากกว่าดิบอย่างมีความสุข
ทางออก sanest คือ:
- ตั้งค่าการเข้ารหัสภายในของ PHP เป็น UTF-8
- บันทึกไฟล์ต้นฉบับทั้งหมดของคุณเป็น UTF-8
- ใช้ UTF-8 เป็นการเข้ารหัสเอาต์พุตของคุณ (อย่าลืมส่ง
Content-type
ส่วนหัวที่เหมาะสม)
- ตั้งค่าการเชื่อมต่อฐานข้อมูลเพื่อใช้ UTF-8 (
SET NAMES UTF8
ใน MySQL)
- กำหนดค่าทุกอย่างเป็น UTF-8 ถ้าเป็นไปได้
- สำหรับสิ่งใดก็ตามที่คุณไม่สามารถควบคุมได้ (เช่นบริการเว็บของบุคคลที่สาม) ตรวจสอบให้แน่ใจว่าคุณรู้การเข้ารหัสและแปลงเป็น UTF-8 โดยเร็วที่สุดและกลับไปที่การเข้ารหัสอื่น ๆ โดยเร็วที่สุด
ทำไมต้อง UTF-8 เนื่องจากสามารถแสดงอักขระ Unicode ทั้งหมดและแทนที่การเข้ารหัสที่มีอยู่ 7 บิตและ 8 บิตที่มีอยู่ทั้งหมดและเนื่องจากเป็นไบนารีที่เข้ากันได้กับ ASCII นั่นคือสตริง ASCII ที่ถูกต้องทุกตัวนั้นยังเป็นสตริง UTF-8 ที่ถูกต้อง (แต่ไม่ใช่ vv .)
ในตัวอย่างของคุณสิ่งที่เกิดขึ้นคือสิ่งนี้
ก่อนอื่นให้คุณบันทึกไฟล์ต้นฉบับของคุณ เครื่องมือแก้ไขข้อความของคุณอาจได้รับการกำหนดค่าให้ใช้ UTF-8 ดังนั้นตัวอักษรสตริงของคุณจึงสิ้นสุดการเข้ารหัส UTF-8 บนดิสก์ PHP อ่านไฟล์นี้แปลสตริงเป็นชุดของไบต์ $original
ตอนนี้มีสตริงที่เข้ารหัส UTF-8 จำนวน 7 ตัวอักษรซึ่งเป็นเพียงลำดับไบต์ (แม้ว่าจะมีมากกว่า 7 ไบต์เพราะอักขระแต่ละตัวจะถูกแทนด้วยสองหรือมากกว่า) หากคุณโทรแล้วecho $original
สตริงที่เข้ารหัสจะถูกส่งไปยังไคลเอ็นต์ตามสภาพ ถ้าคุณบอกให้ลูกค้าคาดหวังว่า UTF-8 ทุกอย่างก็ใช้ได้ แต่ถ้าคุณไม่มี PHP ก็ไม่มีทางที่จะบอกความแตกต่างและคุณจะพบกับขยะในเบราว์เซอร์ เป็นการทดลองให้ลองสิ่งนี้:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
strlen
เป็นการเข้ารหัส - ผู้ไม่เชื่อเรื่องพระเจ้าและถือว่าการเข้ารหัส 8 บิตความกว้างคงที่นั่นคือหนึ่งไบต์ต่อตัวอักษรดังนั้นมันจะนับไบต์ไม่ใช่ตัวอักษร