วิธีการตั้งค่าส่วนหัว HTTP เป็น UTF-8 โดยใช้ PHP ซึ่งใช้ได้ใน W3C validator


319

ฉันมีหลายหน้าPHP ที่สะท้อนสิ่งต่าง ๆ ลงในหน้าHTMLด้วยรหัสต่อไปนี้

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

อย่างไรก็ตามเมื่อฉันตรวจสอบโดยใช้ตัวตรวจสอบ W3Cมันมาพร้อมกับ:

การเข้ารหัสอักขระที่ระบุในส่วนหัว HTTP (iso-8859-1) แตกต่างจากค่าในองค์ประกอบ (utf-8)

ฉันค่อนข้างใหม่กับ PHP และฉันสงสัยว่าฉันควรและควรเปลี่ยนส่วนหัวสำหรับไฟล์ PHP ให้ตรงกับไฟล์ HTML หรือไม่

คำตอบ:


897

ใช้headerเพื่อปรับเปลี่ยนส่วนหัว HTTP:

header('Content-Type: text/html; charset=utf-8');

หมายเหตุเพื่อเรียกใช้ฟังก์ชันนี้ก่อนที่จะส่งเอาต์พุตใด ๆ ไปยังไคลเอ็นต์ มิฉะนั้นส่วนหัวก็ถูกส่งไปเช่นกันและคุณก็ไม่สามารถเปลี่ยนแปลงได้อีกต่อไป headers_sentคุณสามารถตรวจสอบว่ามีการ ดูหน้าคู่มือของheaderสำหรับข้อมูลเพิ่มเติม


4
ฉันจะเพิ่มเฉพาะเมื่อคุณตั้งค่าส่วนหัว HTTP อย่างถูกต้องเช่นนี้คุณไม่จำเป็นต้องใช้<meta>แท็กอีกต่อไป
Jon

3
@ จอน: ฉันจะใช้ทั้ง HTTP-เทียบเท่าMETAใช้เมื่อเอกสาร HTML ไม่ได้โหลดผ่าน HTTP (เช่นจากดิสก์)
Gumbo

6
วิธีนี้จะใช้งานได้หากคุณกำลังเรียกใช้งาน php เพื่อทำหน้าที่คงที่คุณควรบันทึกไฟล์ html ของคุณเป็น utf-8 การทำเช่นนั้นจะเพิ่มอักขระ BOM utf-8 ที่เข้ารหัสไว้ที่จุดเริ่มต้นของไฟล์ ไบต์ 0xEF, 0xBB, 0xBF เพิ่มไปยังจุดเริ่มต้นของไฟล์ เว็บเซิร์ฟเวอร์ส่วนใหญ่จะสังเกตเห็นสิ่งนี้และใช้ส่วนหัวที่เหมาะสม ในความเป็นจริงการบันทึกไฟล์ php ของคุณเป็น utf-8 จะทำให้สำเร็จในสิ่งเดียวกัน
Rahly

1
@ Jeremy Walton: การเพิ่ม UTF-8 BOM ไม่จำเป็นต้องเกิดขึ้น ในความเป็นจริงแล้วมันไม่จำเป็นแม้แต่สำหรับ UTF-8 เพราะมันมีเพียงคำสั่งไบต์เดียว (แต่มันสามารถใช้เพื่อระบุ UTF-8)
Gumbo

1
@Gumbo: แน่นอนว่าฉันลดความซับซ้อนของที่นี่และกำหนดเป้าหมายสถานการณ์ทางเว็บที่พบบ่อยที่สุด (คำถามดูเหมือนจะพูดถึงสถานการณ์นี้) โดยคำนึงถึงระดับที่ชัดเจนของคำถามทำไมบางสิ่งบางอย่างเมื่อคุณไม่เข้าใจว่ามันอาจมีประโยชน์อะไรสักวัน?
Jon

32

ทำให้แน่ใจว่าครั้งแรก PHP ไฟล์ตัวเองเป็นUTF-8เข้ารหัส

เบราว์เซอร์บางตัวเมตาแท็กจะถูกละเว้น หากคุณใช้อักขระ ASCII เพียงตัวเดียวก็ไม่สำคัญ

http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

header('Content-Type: text/html; charset=utf-8');

15

นี่เป็นปัญหากับเว็บเซิร์ฟเวอร์ของคุณที่ส่งส่วนหัว HTTP ที่ไม่ตรงกับที่คุณกำหนด สำหรับคำแนะนำเกี่ยวกับวิธีทำให้เซิร์ฟเวอร์ส่งส่วนหัวที่ถูกต้องให้ดูหน้านี้

มิฉะนั้นคุณสามารถใช้ PHP เพื่อแก้ไขส่วนหัวได้ แต่ต้องทำก่อนที่จะแสดงข้อความใด ๆ โดยใช้รหัสนี้:

header('Content-Type: text/html; charset=utf-8');

ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการส่งออกหัวโดยใช้ PHP สามารถพบได้ในเอกสารสำหรับการทำงานของส่วนหัว


12

คุณยังสามารถใช้วิธีที่สั้นกว่า:

<?php header('Content-Type: charset=utf-8'); ?>

ดูRFC 2616 สามารถระบุชุดอักขระได้เท่านั้น


ฉันชอบตัวเลือกนี้เนื่องจาก (ฉันถือว่า) มันจะช่วยให้คุณสามารถตั้งค่าส่วนอื่น ๆ ของประเภทเนื้อหาแยกต่างหาก (ตัวอย่างเช่นคุณมีหน้าข้อความ / หน้าธรรมดาและหน้าข้อความ / html แต่เป็น UTF8 ทั้งหมด) ความเข้าใจของฉันถูกต้องหรือไม่
Eric Seastrand

1
ฉันไม่พบส่วนของ RFC 2616 ที่ระบุว่าถูกต้องเพื่อระบุวิธีดังกล่าว Content-Type = "Content-Type" ":" media-typeและmedia-type = type "/" subtype *( ";" parameter )
AI0867

1
ไม่ถูกต้องที่จะระบุชุดอักขระเท่านั้น ไม่ถูกต้องต่อ RFC 2616 (ซึ่งล้าสมัยแล้ว) หรือต่อ RFC 7231 (ซึ่งไม่ล้าสมัย) หรือ RFC อื่น ๆ ดูstackoverflow.com/questions/41994062/…
sideshowbarker

10

สำหรับการใช้งานที่ถูกต้องคุณต้องเปลี่ยนชุดของสิ่งต่าง ๆ

ฐานข้อมูล (ทันทีหลังการเชื่อมต่อ):

mysql_query("SET NAMES utf8");

// Meta tag HTML (probably it's already set): 
meta charset="utf-8"
header php (before any output of the HTML):
header('Content-Type: text/html; charset=utf-8')
table-rows-charset (for each row):
utf8_unicode_ci

4
การรวมกันของฐานข้อมูลไม่ส่งผลกระทบต่อผลลัพธ์ที่สร้างโดย PHP เนื่องจากข้อมูลถูกเข้ารหัสเป็นรูปแบบดั้งเดิมที่กำหนดค่าให้ใช้กับ PHP ก่อนที่จะถูกส่งคืนให้กับผู้ใช้ ประการที่สอง OP ไม่ได้กล่าวถึงว่าเขาใช้ MySQL ประการที่สาม MyISAM ล้าสมัยและไม่ควรแนะนำเว้นแต่คุณจะรู้ว่าสิ่งที่คุณทำมีเหตุผลที่ InnoDB กลายเป็นค่าเริ่มต้นใหม่
EWit

ในที่สุดรายการทั้งหมดของสถานที่ทั้งหมดเพื่อตั้งค่าการเข้ารหัสอักขระ
Filip OvertoneSinger Rydlo

mysql_query ("SET NAMES utf8"); ก่อนที่แบบสอบถามแบบใช้เลือกข้อมูลของฉันจะแก้ไขปัญหาให้ฉันได้ ขอบคุณ :)
Deepak Goswami

7

PHP ส่งส่วนหัวโดยอัตโนมัติหากตั้งค่าให้ใช้การเข้ารหัสภายใน:

ini_set('default_charset', 'utf-8');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.