วิธีแก้ปัญหา regular expression is too large

วิธีแก้ปัญหา-regular-expression-is-too-large
วิธีแก้ปัญหา-regular-expression-is-too-large

ปัญหา regular expression is too large ใน PHP นั้นเกิดได้จากหลายกรณี แต่สาเหตุหลักของ Warning นั้น มาจากการที่มีปริมาณข้อมูลมากเกินไป ที่ต้องนำไปผ่านกระบวนการ regular expression ในรูปแบบต่าง ๆ เช่น การค้นหาข้อมูลในฐานข้อมูล การตรวจสอบรูปแบบอีเมล เป็นต้น

วิธีแก้ปัญหา regular expression is too large

วิธีแก้ปัญหาคือ การแบ่งข้อมูลที่จะนำไปประมวลผลออกเป็นส่วน ๆ ในบทความนี้จะยกตัวอย่าง การนำข้อมูลแบบ Array จำนวน 15,000 แถว เข้าไป where in ในคำสั่ง MySQL

ถ้าเราเขียน query ตรง ๆ แบบนี้

SELECT `uid` FROM `stock` WHERE uid IN(0, 1, 2, 3, 4, 5, 6, 7, 8, 9.... +15,000 

ผลลัพธ์ที่ได้ก็จะเกิด Warning แบบนี้

Message: preg_match(): Compilation failed: regular expression is too large at offset 93928

วิธีแก้ปัญหาคือให้เราแบ่ง Array หลักเป็น Array 2 มิติใจปริมาณเท่า ๆ กัน ด้วยคำสั่ง array_chunk และค่อย ๆ query ข้อมูลตามลำดับ โดยคั่นด้วยคำสั่ง MySQL OR ตัวอย่างการคิวรี่คือ

SELECT uid FROM stock WHERE ( uid IN(0, 1) OR uid IN(2, 3) OR uid IN(4, 5))

ตัวอย่าง code การใช้การจริงสำหรับ PHP MySQL

$uid_list = array(1,2,3,4,5,6,7,8,9,10);
$uid_list = array_chunk($uid_list,2); // ใช้คำสั่ง array_chunk แบ่ง array เป็น 2 มิติ และมิติละ 2 แถว
$query_string = '';
$last_loop = count($uid_list); // หา loop รอบสุดท้าย
$start_loop = 0;
foreach($uid_list as $uids)
{
     $start_loop++;
     $uids = implode(',',$uids);
     if($start_loop == $last_loop){ // loop รอบสุดท้ายไม่ต้องมี OR
         $query_string .= ' uid IN('.$uids.')';
     }else{
         $query_string .= ' uid IN('.$uids.') OR';
     }
}
$query = $this->db->query('SELECT uid FROM stock WHERE ('.$query_string.')');

จากโค๊ดด้านบน เมื่อลอง run คำสั่งก็จะเห็นว่าไม่พบ Warning แล้ว เพราะเป็นการแบ่งข้อมูล ไม่ให้มีขนาด bytes ใหญ่เกินไป ก่อนนำเข้าไปทำงานในสูตร regular expression รูปแบบต่าง ๆ

Leave a Reply