ปัญหา 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 รูปแบบต่าง ๆ