php strlen() with mbstring

mvc framework รุ่นใหม่ๆมักจะมีฟังก์ชันการทำ validate ตัวแปร ซึ่งหนึ่งในการ validate ที่มักกำหนดขึ้นมาจากการสร้าง model ก็คือ length ซึ่งภายในจะใช้ strlen() และทำให้เกิดปัญหากับเนื้อหาภาษาไทย

เนื่องจากส่วนใหญ่แล้ว เรามักจะใช้ encoding utf-8 ในการเก็บข้อมูล encoding นี้เป็น multi-byte character ซึ่งช่วงตัวอักษรภาษาไทย มักจะใช้พื้นที่ 3 byte ในการเก็บข้อมูล 1 ตัวอักษร ดังนั้น “กขค” หากเก็บเป็น utf-8 แล้วจะใช้พื้นที่เก็บจริงๆ ถึง 9 bytes ฟังก์ชัน strlen() นั้นไม่รู้จัก multi-byte จึงทำให้ length validation นั้นทำงานไม่ถูกต้อง

ฟังก์ชันที่สามารถนับจำนวนตัวอักษร multi-byte ได้ถูกต้องนั้นก็คือ mb_strlen() ซึ่งใช้งานได้เหมือนกับ strlen()

note: บางครั้ง mb_strlen() จะรายงานความยาวไม่ถูกต้อง ขึ้นอยู่กับ environment ของระบบ เราสามารถแก้ไขได้ด้วยการเพิ่ม mb_internal_encoding(‘utf-8′) ไว้ต้น script

ปัญหาคือโค้ดที่เรียกใช้ strlen() มันเป็นส่วนของ framework การไป patch เปลี่ยนเป็น mb_strlen() ในทุกๆฟังก์ชันที่เรียกก็ดูจะลำบากไป หาก framework update version มาใหม่ก็จะต้องไล่ทำอีก

ทางออกของเราคือใช้ option ของ mbstring ที่เรียกว่า mbstring.func_overload ซึ่งจะทำหน้าที่เปลี่ยนฟังก์ชัน strlen() (และฟังก์ชันเกี่ยวกับ string อื่นๆ อีกหลายตัว) ให้ไปเรียกใช้งานฟังก์ชันที่เป็น mbstring version แทน การตั้งค่านี้ จำเป็นต้องสามารถ access configuration ของระบบได้ (php.ini หรือ .htaccess)

mbstring with func_overload enabled

server configuration ที่ตั้งค่า mbstring.func_overload แล้ว

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>