มีคำตอบที่ดีและพยายามตอบคำถามของคุณที่นี่ ฉันไม่ใช่ผู้เชี่ยวชาญการเข้ารหัส แต่ฉันเข้าใจความต้องการของคุณที่จะมีUTF-8 ล้วนๆมาจนถึงฐานข้อมูลของคุณ ฉันใช้การutf8mb4
เข้ารหัสของ MySQL สำหรับตารางเขตข้อมูลและการเชื่อมต่อ
สถานการณ์ของฉันต้มลงไปที่ "ฉันแค่ต้องการให้ sanitizers, validators, ตรรกะทางธุรกิจของฉันและคำสั่งที่เตรียมไว้เพื่อจัดการกับ UTF-8 เมื่อข้อมูลมาจากแบบฟอร์ม HTML หรือลิงก์การลงทะเบียนอีเมล" ด้วยวิธีง่าย ๆ ของฉันฉันเริ่มด้วยแนวคิดนี้:
- พยายามตรวจจับการเข้ารหัส:
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
- หากไม่สามารถตรวจจับการเข้ารหัสได้
throw new RuntimeException
- หากอินพุตคือ
UTF-8
ให้ดำเนินการต่อ
ถ้ามันเป็นISO-8859-1
หรือASCII
พยายามแปลงเป็น UTF-8 (รอไม่ใช่เสร็จ)
ข ตรวจจับการเข้ารหัสของค่าที่แปลงแล้ว
ค. หากค่าการเข้ารหัสและการแปลงที่รายงานมีทั้งคู่UTF-8
ให้ดำเนินการต่อ
d อื่น,throw new RuntimeException
จากระดับนามธรรมของฉัน 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;
}
หนึ่งอาจโต้แย้งว่าผมควรจะแยกความกังวลการเข้ารหัสจากนามธรรมของฉันSanitizer
ระดับและก็ฉีดวัตถุเป็นเช่นเด็กที่เป็นรูปธรรมของEncoder
Sanitizer
อย่างไรก็ตามปัญหาหลักของวิธีการของฉันคือถ้าไม่มีความรู้เพิ่มเติมฉันก็แค่ปฏิเสธประเภทการเข้ารหัสที่ฉันไม่ต้องการ (และฉันพึ่งฟังก์ชั่น PHP mb_ *) หากไม่มีการศึกษาเพิ่มเติมฉันไม่สามารถรู้ได้ว่าสิ่งนั้นสร้างความเสียหายแก่ประชากรบ้างหรือไม่ (หรือถ้าฉันสูญเสียข้อมูลที่สำคัญไป) ดังนั้นฉันต้องเรียนรู้เพิ่มเติม ฉันพบบทความนี้แล้ว
สิ่งที่โปรแกรมเมอร์ทุกคนต้องมีความรู้ในเชิงบวกเกี่ยวกับการเข้ารหัสและชุดอักขระเพื่อทำงานกับข้อความ
นอกจากนี้จะเกิดอะไรขึ้นเมื่อข้อมูลที่เข้ารหัสถูกเพิ่มลงในลิงก์การลงทะเบียนอีเมลของฉัน (โดยใช้OpenSSL
หรือmcrypt
) สิ่งนี้อาจรบกวนการถอดรหัสหรือไม่ แล้ว Windows-1252 ล่ะ? สิ่งที่เกี่ยวกับความปลอดภัย การใช้utf8_decode()
และutf8_encode()
ในSanitizer::isUTF8
มีพิรุธ
ผู้คนได้ชี้ให้เห็นถึงการมาระยะสั้นในฟังก์ชั่น PHP mb_ * ฉันไม่เคยใช้เวลาสำรวจiconv
แต่ถ้ามันทำงานได้ดีกว่าฟังก์ชั่น mb_ * แจ้งให้ฉันทราบ