PlusMagi's Blog By Pitt Phunsanit

บั๊กที่แท้มันคืออะไรตับไตใส้พุง

มี user ถามมาว่า bug คืออะไร ทำไม่มี bug ก็เลยลองเขียนตัวอย่างให้ดู ยกตัวอย่างบัคที่เกิดจาการกรอกข้อมูลผิดไปจากที่ระบบออกแบบและคาดหวังไว้ ก็มีคำถามกลับมาประมาณว่าทำไม่ไม่ตรวจให้หมดละ เลยลองทำตัวอย่างออกมา

<?php $strings = [ '!@#$%^&* () _-+="{}[]\+:<>,./?', 'Apple Inc.', 'email.gmail.com', 'email.job.co.th', 'email@gmail.com', 'email@job.co.th', 'https://pitt.plusmagi.com/about/', 'https://pitt.plusmagi.com/%E0%B9%80%E0%B8%8A%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%A1%E0%B8%95%E0%B9%88%E0%B8%AD-php-%E0%B8%81%E0%B8%B1%E0%B8%9A-sql-server-sqlsrv/', 'james bond 007', 'johnny english พยัคฆ์ร้าย 00ก๊าก', 'pitt@小米科技.cn', 'sale 20%', 'Xiaomi Inc. (小米科技) ', 'Xiaomi Inc.', 'พิชญ์ พันธุ์สนิท pitt phunsanit', 'พิชญ์ พันธุ์สนิท', 'พิชญ์@gmail.com', 'หนึ่งในพระราชดำริ ช่อง 9', 'หนึ่งในพระราชดำริ ช่อง ๙', 'ไทย นี่มันไทยจริง ๆ ',
]; function validateAlphanumeric ($string) { if (preg_match ('/[^A-Za-z0-9]/', $string)) { return true; } else { return false; }
} function validateAlphanumericEnglish ($string) { if (preg_match ('/^[a-zA-Z0-9\s]+$/', $string)) { return true; } else { return false; }
} function validateAlphanumericThai ($string) { if (preg_match ('/[^A-Za-z0-9-ก-๙]/', $string)) { return true; } else { return false; }
} function validateAlphanumericThaiOnly ($string) { /* อักษรภาษาไทย และ space */ if (preg_match ('/^[ก-ฮ\s]+$/', $string)) { return true; } else { return false; }
} function validateEmail ($string) { if (filter_var ($string, FILTER_VALIDATE_EMAIL)) { return true; } else { return false; }
} function validateFilterURL ($string) { if (filter_var ($string, FILTER_VALIDATE_URL)) { return true; } else { return false; }
} function validatePregURL ($string) { if (preg_match ('/\b (?: (?:https?|ftp) :\/\/|www\.) [-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i', $string)) { return true; } else { return false; }
} echo '<!doctype html>
<html> <head> <meta charset="utf-8"> <title>PHP String Validation By Ptii Phunsanit</title> <meta name="author" content="Pitt Phunsanit"> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css"> </head> <body> <table class="table table-striped"> <caption> PHP String Validation </caption> <thead> <tr> <th>Test</th> <th>String</th> <th colspan="4">Alphabet</th> <th>Email</th> <th colspan="2">URL</th> </tr> <tr> <th></th> <th></th> <th>Alphanumeric</th> <th>Alphanumeric English</th> <th>Alphanumeric Thai</th> <th>Alphanumeric Thai Only</th> <th>Email</th> <th>Filter URL</th> <th>Preg URL</th> </tr> </thead> <tbody>';
foreach ($strings as $no => $string) { echo '<tr>', '<th>', ($no + 1) , '</th>', '<th>', $string, '</th>', '<td>', (int) validateAlphanumeric ($string) , '</td>', '<td>', (int) validateAlphanumericEnglish ($string) , '</td>', '<td>', (int) validateAlphanumericThai ($string) , '</td>', '<td>', (int) validateAlphanumericThaiOnly ($string) , '</td>', '<td>', (int) validateEmail ($string) , '</td>', '<td>', (int) validateFilterURL ($string) , '</td>', '<td>', (int) validatePregURL ($string) , '</td>', '</tr>';
}
echo '</tbody></table></body></html>';
ผลที่ได้ ดูเต็ม ๆ เว็บนี้ยังมี bug เลย แต่ไม่คุ้มที่จะแก้
1 คือผ่านการทดสอบ 0 คือ ไม่ผ่านการทดสอบ

PHP String Validation
Test String Alphabet Email URL
Alphanumeric Alphanumeric English Alphanumeric Thai Alphanumeric Thai Only Email Filter URL Preg URL
1 !@#$%^&* () _-+=”{}[]\+:<>,./? 1 0 1 0 0 0 0
2 Apple Inc. 1 0 1 0 0 0 0
3 email.gmail.com 1 0 1 0 0 0 0
4 email.job.co.th 1 0 1 0 0 0 0
5 email@gmail.com 1 0 1 0 1 0 0
6 email@job.co.th 1 0 1 0 1 0 0
7 https://pitt.plusmagi.com/about/ 1 0 1 0 0 1 1
8 https://pitt.plusmagi.com/%E0%B9%80%E0%B8%8A%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%A1%E0%B8%95%E0%B9%88%E0%B8%AD-php-%E0%B8%81%E0%B8%B1%E0%B8%9A-sql-server-sqlsrv/ 1 0 1 0 0 0 1
9 james bond 007 1 1 1 0 0 0 0
10 johnny english พยัคฆ์ร้าย 00ก๊าก 1 0 1 0 0 0 0
11 pitt@小米科技.cn 1 0 1 0 0 0 0
12 sale 20% 1 0 1 0 0 0 0
13 Xiaomi Inc. (小米科技) 1 0 1 0 0 0 0
14 Xiaomi Inc. 1 0 1 0 0 0 0
15 พิชญ์ พันธุ์สนิท pitt phunsanit 1 0 1 0 0 0 0
16 พิชญ์ พันธุ์สนิท 1 0 1 1 0 0 0
17 พิชญ์@gmail.com 1 0 1 0 0 0 0
18 หนึ่งในพระราชดำริ ช่อง 9 1 0 1 0 0 0 0
19 หนึ่งในพระราชดำริ ช่อง ๙ 1 0 1 1 0 0 0
20 ไทย นี่มันไทยจริง ๆ 1 0 1 1 0 0 0

เริ่มจากชุดแรก Alphanumeric ใช้ preg_match (‘/[^A-Za-z0-9]/’, $string เหมือนจะดูดี ตามคู่มือคือเทียบโดยตัวอักษร a ถึง z และตัวเลข 0 ถึง 9 แต่ขอโทษชุดสตริงค์ แปลก ๆ ?!@#$%^&* () _-+=”{}[]\+:<>,./ มันยังผ่าน จนด้วยคำพูดจริง ๆ ใส่อะไรก็ผ่าน

ชุดที่ 2 Alphanumeric English ใช้ preg_match (‘/^[a-zA-Z0-9\s]+$/’, $string) ผลคือ ที่มีอักษรไทยอยู่ตกหมด และ james bond 007 ผ่าน แต่ Apple Inc. กับตัวอื่น ๆ ตกไปง่าย ๆ แค่ใส่ . สรุปถ้าเขียนเป็นประโยคมาก็จบชีวิต

ชุดที่ 3 Alphanumeric Thai ใช้ preg_match (‘/[^A-Za-z0-9-ก-๙]/’, $string) รั่วทุกตัวอักษรอีกชุก ถึงจะใส่ ก-๙ มาอักษรจีนก็ยังรอดอยู่ดี

ชุดที่ 4 Alphanumeric Thai Only ใช้ preg_match (‘/^[ก-ฮ\s]+$/’, $string) มันไทยมากจริง อย่าได้ใส่เลขอารบิกมาเชียว บางคนก็ไม่รู้นะครับว่าเลขไทยนะมันพิมพ์ยังไง

ชุดที่ 5 Email ใช้ filter_var ($string, FILTER_VALIDATE_EMAIL) ตรวจว่าเป็นอีเมลจริง ๆ รึเปล่า ผ่าน email.gmail.com และ พิชญ์@gmail.com ก็หลอกมันไม่ได้

ชุดที่ 6 ติดใจคำสั่ง filter_var ในข้อที่แล้วใช้ filter_var ($string, FILTER_VALIDATE_URL) ผลคือ เกือบจะดีแล้ว ตรวจ url ได้จริง ๆ ยกเว้น https://pitt.plusmagi.com/%E0%B9%80%E0%B8%8A%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%A1%E0%B8%95%E0%B9%88%E0%B8%AD-php-%E0%B8%81%E0%B8%B1%E0%B8%9A-sql-server-sqlsrv/ link ของบล๊อคของผมเองยังไม่ผ่าน ปวดตับ แม้แต่ function สำเร็จรูปก็ไม่ได้ดีเสมอตามที่คิดว่า “ใช้กันมากเป็นมาตราฐานมันต้องดีกว่าเขียนเองซิ” function filter_var ของ PHP มันออกมาตั้งแต่ 2 November 2006 ก็แค่ไม่กี่ปีเองมั๊ง ปีนี้ ค.ศ. อะไรแล้ว แต่มันก็ยังไม่รับภาษาอื่นนอกจากภาษาอังกฤษอยู่เหมือนเดิม ไม่ใช่ไม่มีคนแจ้งไปที่คนเขียนภาษา php นะ ตามนี้ แต่พี่แกก็ยังไม่แก้แค่นั้นเอง

ชุดที่ 7 ใช้ preg_match (‘/\b (?: (?:https?|ftp) :\/\/|www\.) [-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i’, $string) ยาวยืดอย่าพิมพ์ผิดเชียว ผมก็ก๊อบเค้ามา แต่ตรวจ url ได้ถูกต้อง

ที่ทำตัวอย่างให้ดูสรุปคือ ในการเขียนโปรแกรมไม่มีอะไรที่ทำงานได้ดี 100% เต็ม ทำอย่างหนึ่งจะมีการแลกเปลี่ยนที่เท่าเทียม (รึเปล่า) ตามมาด้วยเสมอ อย่างตรวจ link แบบชุดที่ 6 จริง ๆ มันตรวจว่าเป็นลิงค์เว็บจริง ๆ มาได้หลายปีแล้ว แต่เว็บหลัง ๆ เน้นทำ SEO กับท้องถิ่นตามภาษาและประเทศมากขึ้นแทนที่จะใช้ภาษาอังกฤษอย่างเดียว ตอนนี้เลยต้องมาเขียนตัวตรวจสอบกันแบบยาว ๆ และปวดตับมากกกก

การที่กว่าจะได้งานที่สมบูรณ์ที่สุดไกล้ความสมบูรณ์แบบถึงต้องใช้พลังและความร่วมมือจากทุก ๆ คน และมีค่าใช้จ่ายและเวลาที่สูงมาก ผลคือ การลดค่าใช้จ่ายอย่าง

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

Exit mobile version