มี user ถามมาว่า bug คืออะไร ทำไม่มี bug ก็เลยลองเขียนตัวอย่างให้ดู ยกตัวอย่างบัคที่เกิดจาการกรอกข้อมูลผิดไปจากที่ระบบออกแบบและคาดหวังไว้ ก็มีคำถามกลับมาประมาณว่าทำไม่ไม่ตรวจให้หมดละ เลยลองทำตัวอย่างออกมา
<?php $strings = [ '!@#$%^&*()_-+="{}[]\+:<>,./?', 'Apple Inc.', 'email.gmail.com', 'email.job.co.th', '[email protected]', '[email protected]', 'https://pitt.plusmagi.com/about/', 'https://pitt.plusmagi.com/เชื่อมต่อ-php-กับ-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 คือ ไม่ผ่านการทดสอบ
Test | String | Alphabet | URL | |||||
---|---|---|---|---|---|---|---|---|
Alphanumeric | Alphanumeric English | Alphanumeric Thai | Alphanumeric Thai Only | 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 protected] | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
6 | [email protected] | 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/เชื่อมต่อ-php-กับ-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/เชื่อมต่อ-php-กับ-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 กับท้องถิ่นตามภาษาและประเทศมากขึ้นแทนที่จะใช้ภาษาอังกฤษอย่างเดียว ตอนนี้เลยต้องมาเขียนตัวตรวจสอบกันแบบยาวๆ และปวดตับมากกกก
การที่กว่าจะได้งานที่สมบูรณ์ที่สุดไกล้ความสมบูรณ์แบบถึงต้องใช้พลังและความร่วมมือจากทุกๆคน และมีค่าใช้จ่ายและเวลาที่สูงมาก ผลคือ การลดค่าใช้จ่ายอย่าง
- บอกมานิดเดียว น้องไปคิดต่อเอาเองนะ พี่มางานอื่น (พี่ครับ ผมต้องเขียน business plan ต้องมาคิดให้ว่าบริษัทพี่นี่ มันขายอะไร ต้องทำยัง บริการอะไรบ้าง และมันทำงานยังไง สุดท้ายก็ออกมาขาดๆ เกินๆ)
- ไม่จ้าง tester ครับ programmer เขียนเสร็จก็ต้องมาลองเอง เพราะว่าออกแบบและเขียนเองมากะมือ มันเลยจำติดอยู่ในสมองว่า ตรงนี้ต้องกรอกอะไร ตอนทดสอบ ก็เผลอทำแบบเดิม ทำมาให้กรอกตัวเลข ต้อนทดสอบก็ใส่ 1555, 5544, 444, 85 มัวๆไป ตอนให้ user ทำลองใช้ มีคนใส่โง่ๆ “100 บาท” เกิดอะไรขึ้น
- โปรแกรมก็เอา 100 บาท ไปใส่ในสูตร
จำนวนบาท คูณจำนวน ก็ออกมาเป็น
100บาท x 5 = ?
แล้วก็บอกกลับมาว่า พ่องมึง คูณได้เหรอวะ แต่มันบอกมาแบบที่มีแต่โปรแกรมเมอร์ที่เข้าใจ แลัวฆ่าตัวตายไปต่อหน้าต่อตา - บัญชีก็บอกว่า นี่ทำเสร็จแล้วเหรอ เทสแล้วแน่นะ
- คนเขียนเห็นก็อยากจะบอกว่า ข้างหลังใส่ label บาทให้ละ จะกรอกไปทำซากอะไร
- ทีนี้เกินอะไรขึ้นต่อไปในการประชุม
- project manager ก็บอกว่านิดหนึ่งพี่ แก้ไม่ถึง 5 นาทีก็เสร็จแล้วครับ
- programmer คิด มึงเคยถามกูยัง ทำไงต่อ ทำนานปะ แก้แล้วตรงไหนจะพังมั่ย แล้วอย่างอื่นมันจะทันป่าว
- บัญชีของลูกค้าก็คิด ขี้เกียจเทสแน่ๆ เมื่อไหร่จะได้ใช้
- เซลล์ก็คิด ทำไม่ไม่เอาใบส่งสินค้าที่เขียนกับมือ เข้าเครื่องถ่ายเอกสาร แล้วได้รายงานออกมาเลย ไม่เสียเวลา เอาไปขายให้ที่ไหนมีแต่คนอยากซื้อ ทำไม่ไม่ยอมทำ จะได้ขายง่ายๆ ซักที % จะได้เยอะๆ อุสาห์คิดให้ดีๆ ไม่เข้าใจ
- ลูกค้า ก็คิด รู้งี้ยอมจ่ายอีกนิดจ้างอีกเจ้า ยอมไม่ไปเที่ยวเมืองนอกก็ได้ จะได้ทำอย่างอื่นซะที
- จ้างมาแพง ต้องรีบๆทำงาน ให้ได้ function ผลคือไม่ได้ test งานจริงๆ หรือให้มันใช้งานได้ง่าย อย่างงานที่เคยเจอต้องมีคนมา เอารูปถ่ายสินค้ามาตัดให้พอดีกับขนาดที่ใช้ในเว็บ ทั้งๆที่ ก็ถ่ายโดยกล้องเดิม ขนาดเดิม และมุมกล้องเดิมทุกวัน ทุกชิ้น ถ้ายอมให้เวลาเขียนโปรแกรมเพิ่มอีกนิด ก็แค่วางของที่เดิม กดถ่ายรูปแล้วโยนให้โปรแกรมมันตัดรูป เปลี่ยนขนาด แล้วเอาให้ลูกค้าดูเอง ประหยัดเวลาในชีวิตออกไปได้เยอะเลยแท้ๆ แต่พี่รีบ พี่ไม่อยากจ่ายเงินเพิ่ม
- โปรแกรมก็เอา 100 บาท ไปใส่ในสูตร
มันก็เหมือนคำพูดที่ว่า ของดีไม่แพง นั้นละครับ ยอมจ่ายได้แค่ไหน คนขายก็ประมาณ ต่อกันอย่างนี้ ขอฟรีเลยมั๋ยพี่ ที่สำคัญคือ จะหาจุดสมดุลย์ได้ที่ไหน ถึงจะพอใจกันทั้งสองฝ่าย