ITKMITL PHP Competition

สำหรับบล็อควันนี้ @Fantasier request มาครับว่าอยากให้ blog เกี่ยวกับการแข่ง PHP ในงาน openhouse ที่คณะ IT ลาดกระบัง

ก็ไปถึงรถติดในม. โคตรๆ ครับ ผมนึกว่าจะไม่ทันอยู่แล้ว เข้าไปเค้าบอกอีกสิบนาทีเริ่ม แต่เอ๊ะ ลงชื่อแล้วแฟนต้าเสี่ยยังไม่เห็นมา ไม่เป็นไร รีบลงรีบเข้าแข่ง

มาถึงโจทย์นะครับ โจทย์นี้จะประกาศเมื่อเริ่มแข่ง ผมเลยต้อง skim อ่านอย่างไวได้ความประมาณว่าแพนด้าอยากคุยกัน เลยให้ทำ Panda chat lnw โดยมีแชทรูทต่างๆ ให้เข้าไปแชทได้ จะต้องมีการแสดง user online มีระบบกรองคำหยาบและ emoticon

แข่งอันนี้ดีอย่างครับ เค้าจะมีภาพกราฟฟิคต่างๆ ให้เลย คือไม่ต้องไปนั่งทำเองเหมาะสำหรับคนทำกราฟฟิคไม่เก่งแบบผม ให้ใช้เวลาโฟกัสกับโค้ดได้เลย

สำหรับชั่วโมงแรกนะครับ ผมปั่น register ก่อนเป็นอย่างแรก​โดยออกแบบฐานข้อมูลตามโจทย์ให้มาเป๊ะ แล้วก็ form ตามโจทย์เลย แต่โค้ดสำหรับการสมัครนี่สิครับนั่งเขียนยาวมาก โดยทำ design ที่ว่าไปก่อนนี้ประมาณ 20 นาทีส่วนอีก 40 นาทีเป็นโค้ดสมัครครับ โดยจะต้องมี input validation แทบทุกช่อง และผมเองลืม print regular expression มา​​ ฉะนั้นเดาสดครับ ก็โชคดึว่ามันไม่ค่อยบั๊กเลยสามารถเสร็จได้ทัน ส่วนการ login นั้นแค่ดึงมาเช็คอยู่แล้วครับเขียนไม่นาน และการตรวจสอบ user ผมจะแยกเป็น function ไว้อยู่แล้ว ซึ่งจะเขียนเป็นลำดับแรกๆ (แนวนี้ผมได้ไอเดียจากฟังก์ชั่น is_user_logged_in ของ WordPress ครับ และ project Sora เองก็มีฟังค์ชั่นนี้)

ต่อมาครับเป็นรายการแชท ถึงตรงนี้ผมเองว่าน่าจะเริ่มออกแบบฐานข้อมูลได้แล้ว เลยทำทีเดียวให้เสร็จครับ บังเอิญว่าโจทย์ตรงกับแชทที่ผมเคยทำมาก่อน เลยออกแบบตามของ bd2.in.th อันเก่าไปเลย (อันเก่าผมเขียนด้วยอารมณ์โมโหครับ ทำเสร็จในวันเดียวได้ แต่เห็นโจทย์วันนี้ตอนแรกผมเองยังว่าไม่น่าจะเสร็จทัน AJAX) ก็จะมีตารางสำหรับเก็บห้องแชท เก็บข้อความในแชท เก็บ user online ครับ เสร็จแล้วการ list ก็ไม่ยากครับดึงมาใส่ตัวแปร แล้วผมจะแยกส่วนของ template (view) ไปอีกไฟล์เลย (คือแยก view-controller ชัดเจน ส่วนถ้าจะมี model ใน PHP layer คงไม่ทันครับ)

ถัดมาของห้องแชทครับ ตรงนี้ผมก็ทำ layout ให้เสร็จก่อน จากนั้นจึงเริ่มที๋โค้ด ผมตัดสินใจว่าจะไม่ gratefully degrade (project sora ถ้าปิด javascript จะเห็นข้อความเก่าแต่ทำอะไรไม่ได้ครับ) แต่จะดึงข้อความด้วย javascript 100% เลย (คือถ้าปิด javascript จะไม่เห็นข้อความ) จากนั้นก็เขียน chat server ขึ้นมาครับ โดยเป็นไฟล์ที่จะไปเรียกเอารายการแชทล่าสุดมาทำ JSON ให้แล้วส่งกลับ จากนั้น JavaScript จะหาว่า ID ล่าสุดที่เคยประมวลผลไปคือเลขอะไร แล้วก็จะไม่ประมวลผล ID ที่น้อยกว่าเลขนั้นทำให้ข้อความไม่ซ้ำถึง server จะส่งมาซ้ำ ต่อมาครับก็จะเป็นการส่ง ส่งไปแล้วจริงๆถ้าให้ไวมันจะต้องคืนข้อความมาให้เราประมวลผลใน client ได้ครับ แต่ด้วยความขี้เกียจผมเลยไม่คืนอะไรมา แล้วให้ client ดึงแชทใหม่อีกรอบไปเลย จบ

ถึงตรงนี้ได้ผมก็เหลือแต่ส่วนเดียวแล้วแหละครับ คือ user online ตรงนี้อัลกอรึธึมยาก ผมเชื่อว่ามีวิธีง่ายกว่านี้ (เพราะโจทย์กำหนด และแชทอื่นๆ เค้าทำได้) แต่ผมไม่รู้ครับ วิธีที่ผมใช้คือ client จะ poll server เป็นระยะ ตัว server จะเก็บเวลาที่ poll ไว้ แล้วคืนไปว่าใน 5 วิเนี่ยมีใครติดต่อมาบ้าง จากนั้น client จะเปรียบเทียบจากข้อมูลเก่ากับข้อมูลใหม่ว่ามีใครหายไปหรือเข้ามาบ้างครับแล้วก็จะทำการแสดงข้อความ (แชทของ bd2 อันเก่าใช้วิธีนี้ แต่จะวาด list ใหม่เลยไม่มีการถอด user ออกทีละคนได้ ส่วนแชทปัจจุบันวิธีเก็บ user online ซับซ้อนกว่านี้ครับเพราะใช้ websocket ไว้ถ้ามีโอกาสจะมาเล่า) แล้วก็สำหรับ user online ในหน้าแรกครับ บังเอิญนึกถึง GROUP BY ที่อยากเล่นอยู่ เลยลองเขียนไปดูว่า `SELECT room, COUNT(*) cnt FROM online WHERE room=1 AND time >= ‘time()-5’ GROUP BY room` แล้วมันก็ได้ผลครับ ทำให้มันดึงทีเดียวหลายห้องได้ใน query เดียว​ (bluewavechat ยังต้องนั่งดึงทีละเพลงเลยครับ)

ที่เหลือก็เก็บรายละเอียดครับ พวกกรองคำหยาบ และ emote และที่สำคัญมากคือเวลาอ่านแชทข้างบนอยู่มันจะไม่ autoscroll

สำหรับการ present นะครับ ผมพูดตาม slide ที่เตรียมไป กรรมการเองยังงงๆ กับเรื่อง salt ที่ผมเน้นย้ำด้วยแหละครับ (ผมรู้จัก salt จาก SMF น่ะครับ — กรรมการก็ถามเรื่องนี้) แล้วก็ที่โดนท้วงมาก็จะมี IE ที่ผมพลาดลืมเช็ค แล้วก็เรื่อง autoscroll บั๊กนิดหน่อยครับ นอกจากนี้ผมยังพูดเรื่อง WebSocket ที่เป็นชื่อทีมไปด้วยว่าถ้าได้ใช้แชทคงจะเจ๋งกว่านี้ (ถ้าทันเวลา) นะครับ เค้าก็เลยถามถึงเรื่องตรงนี้หน่อยซึ่งผมก็อธิบายแชทของ bd2.in.th ไปให้ฟัง

สำหรับผลการแข่งขัน ได้ที่ 1 ครับ ทุนการศึกษา 4,000 บาทและโควต้า งานนี้ต้องขอบคุณ bd2.in.th นี่แหละครับที่ทำให้ผมได้เขียนแชทสองตัวฝึกประสบการณ์

ปล. ผมว่าโจทย์มันเน้นที่ AJAX ไปนะครับ คือแชทที่เขียนไม่ใช้ AJAX นี่มันจะแบบว่าไม่เร้าใจเลยแล้ว present ไม่มัน มันมีอีกหลายๆ อย่างนะครับที่ไม่มี AJAX ก็ได้ บางอย่างใช้ AJAX แล้วมันจะเป็นส่วนเกินด้วยซ้ำ

WMC Web Contest 2011

จริงๆ เรื่องการแข่งน่าจะเคลียร์จบไปใน Twitter แล้ว แต่บอก @winwanwon @Fantasier ไว้ว่าจะ blog ก็เลยต้องมา blog (ที่รับปากไว้คือไม่อยากพูดมากในงาน แต่สุดท้ายก็พูดซะยาว)

ท้าวความเดิม​ @Fantasier เอาลิงก์ IT-ThaiNichi มาแปะซึ่งเป็นการแข่งทำเว็บ ผมเองก็ว่า เออ น่าสนใจ เลยไปถามเพื่อนว่าใครจะมามั้ย แต่ก็เกรงใจต้นกล้าว่าเค้าเป็นคนชวนมาก็ไม่อยากไปแย่งเค้า (จริงๆ ผมก็กลัวเค้าเพราะเค้าทำ design สวยกว่า ส่วนเค้าก็กลัวผมว่าผมทำ code เก่งกว่า) ก็เลยบอกเพื่อนที่โรงเรียนว่าต้องให้ครบสามคนถึงจะไป ปรากฎว่าถามไปถามมาแล้ว ได้แค่ 2 คนเพราะมันเป็นวันชดเชย รด. พอดี วันต่อมา @onsanookza GTalk มาถามก็เลยตกลงไปกัน

ทีนี้จะไปกันก็ต้องตกลงกันก่อน ก็ประชุมทีมกันซึ่งเค้าผลักให้ผมเป็นหัวหน้าทีม ก็โอเค ถัดมาก็เรื่องชื่อทีม คิดกันมาหลายชื่อมากๆ อ้นเสนอ lol แต่เห็นต้นกล้าจะใช้ชื่อ lolz แล้วก็เลยเอา LOLWUT ไปเข้ารหัส base64 ได้ TE9MV1VU ซึ่งผมก็โอเคว่ามันจำง่าย ตัวอักษรสองตัวเลขหนึ่งตัว และไม่มีใหญ่เล็กสลับกัน (ถ้า LOL เฉยๆ เข้ารหัสแล้วมันคือ TE9M ซึ่งคนอาจจะเดาว่ามันมาจากเอา 9 แทนตัว A ซึ่งไม่ใช่ เลยเลี่ยง) การประชุมครั้งนั้นไม่ใช่ง่ายครับ เพราะ Google Talk มันประชุมกลุ่มไม่ได้ (XMPP น่ะทำได้ แต่ Google ดันทำครึ่งๆ กลางๆ) ก็เลยตกลงว่าจะใช้ Skype ขณะนั้นผมก็เพิ่งแข่ง Hackathon จบมา ก็เลยต้องหาสถานที่มีเน็ต มีข้าวกิน และมี Pump it up ก็คือ Esplanade ซึ่งนึกว่าเกมมันจะสั้นๆ ปรากฎว่าเล่นทีเป็นชั่วโมงครับ กว่าจะได้ประชุมอีกสองคนก็ใกล้เวลานอนกันแล้ว

พอถึงวันก่อนแข่ง ทีมโน้นเค้าเตรียม CMS กันคร่ำเคร่ง ส่วนผมก็ใช้ Django ซึ่งมันมี admin สำเร็จรูป มี ORM ทำอะไรก็สบายไม่ต้องไปนั่งจิ้มโค๊ดเยอะๆ และก็เลยว่าให้สมาชิกเตรียมออกแบบกันมา โดยผมให้ดูตัวอย่างจากสุดยอดเว็บสวย 2 เว็บที่ผมอยากเจอคนเขียนมาก คือ [Lubd Hostel](http://siamsquare.lubd.com) และ [Cubiccreative](http://cubiccreative.org/creativecamp7/) โดยพ่อแนะนำอันหลังว่าน่าจะทำทันในเวลามากกว่า

พอมาถึงวันแข่ง เริ่มงานมาได้ concept ชื่อ “การศึกษาในฝัน” ตอนแรกผมยังนึกไม่ออกว่าจะทำเนื้อหายังไง จนพอเริ่มทำ mockup แล้วคำว่า ในอนาคต มันเข้ามาในหัว ก็เลยเขียนไปว่า ศึกษาต่อในประเทศ ศึกษาต่อต่างประเทศ และ นีท!! (เขียนจริงๆ เมนูนีทก็เคยมีมาแล้ว) แล้วก็ออกแบบคร่าวๆ มา ซึ่งอ้นติดใจหัวเว็บจากเว็บหลับดี ที่เห็นแล้วอยากได้มาก ก็เลยทำหัวโค้งสนอง need ให้มี fade เหมือนกัน

ถัดมาก็แบ่งกันทำงาน อ้นทำตัวหัวเว็บ เติมให้ไปค้นข้อมูลมาแล้วก็ทำหัวข้อ ทำภาพประกอบ ส่วนเราระหว่างนั้นก็ละเลง CSS ให้พร้อมรับหัวเว็บและ content ซึ่งตัว content เสร็จก่อน (ใช้เวลาเป็นชั่วโมง) ซึ่งก็ใส่ content ไปได้หลายอันแล้วกว่าหัวเว็บจะเสร็จ

ตัวหัวเว็บนี่ยากครับ เพราะสังเกตว่ามันจะ fade ได้ ฉะนั้นต้องมีหลายชิ้น ปัญหาที่เจอคือภาพพื้นหลังนี่แหละครับ ไม่รู้จะเอาภาพอะไร สุดท้ายภาพมันเลยเล็กๆ ทำให้ผมรู้สึกว่าการ fade มันไม่ wow เท่ากับของหลับดี ที่ fade จุดใหญ่ๆ ให้ตระการตาไปเลย

สำหรับ content ก็จัดปาซ้ายสลับขวาไปนั่นแหละครับ แต่คือต้องดูเรื่อง margin padding ให้ดีว่ามันสวยงามเหมาะสมแล้ว และกว่าจะทำเสร็จทั้งหมดก็เรียกได้ว่าไม่ทันในเวลาที่กำหนดเลยแหละครับ

ถัดมาเป็นการ present งานฉบับรวบรัดครับ คือกินข้าว 15 นาทีแล้วต้องลงมา present ฉะนั้นจะไม่ได้เตี๊ยมอะไรกันมาก ผมบอกว่าโอเค ผมจัดการทุกอย่างได้ ก็เลยเริ่มด้วยการแนะนำทีมทั้งแบบเป็นพิธีการและแบบไม่เป็นพิธีการ (ก็มีคนช่วยขำ ขอบคุณครับ) พอเข้าสู่เนื้อหา เนื่องจากว่าทีมอื่นๆ จะเน้นเรื่องเนื้อหาของเว็บซะมากกว่า ซึ่งผมไม่ค่อยคิดว่าเหมาะกับแข่งเว็บแบบนี้ที่เค้าเน้นการออกแบบเว็บ เลยพูดถึงโครงสร้างของเว็บมากกว่าที่ผมจะชูจุดขายว่า No Flash, Tableless, No Frame ซึ่งทีมอื่นๆ จะใช้กัน ตรงนี้พลาดไปว่ากรรมการที่ไม่ได้เขียนเว็บสมัยใหม่จะไม่เข้าใจว่าทำไม no frame สำคัญ no flash สำคัญ ผมก็ลืมอธิบายไป

สำหรับคำถามที่ถูกถามนะครับ คำถามแรกคือเรื่องการกลับหน้าแรกหาไม่เจอ ซึ่งผมก็ต้องสาธยายโดยยกตัวอย่างเว็บอย่าง Facebook ว่ามันไม่ต้องมี Home กดโลโก้ก็ได้ (ผมเพิ่งนึกออกว่า Facebook ที่ผมพูดถึงตอนนั้นคือ Facebook Touch ไม่ใช่รุ่นบนคอมฯ) แต่ก็ต้องยอมรับว่าโลโก้ไม่เด่นพอที่จะให้เห็นว่ามันคลิกได้ มันเหมือนเป็นเมนูอันนึงไปมากกว่า

คำถามถัดมาที่ถูกถามคือเรื่องเมนูว่าทำไมไว้ข้างบน ซึ่งเว็บที่มาแข่งอื่นๆ จะไม่ทำกัน ตรงนี้คิดนานอยู่กว่าจะตอบได้ โชคดีว่านึกถึงทีมนึงได้ที่แกใช้เมนูแล้วมันเว้นที่ไว้หลังเมนูสุด ก็เลยอธิบายไป (แต่ผมรู้สึกว่าดราม่านะ) ว่า “คนเข้าเว็บเราเข้ามาอ่านเนื้อหาครับ ฉะนั้นตรงนี้ก็เลยจะมีแต่เนื้อหา ถ้ามี sidebar ปุ๊บ พอเมนูสุดมันก็จะเป็นสีขาวครับ พอเลื่อนลงมาก็จะกินที่เนื้อหาไปให้ที่สีขาวอย่างไร้ประโยชน์ เกะกะ ฉะนั้นตัดออกดีกว่าครับ” (นึกถึง blog นี้ก็ได้ครับ สังเกตว่าหน้าเนื้อหาจะไม่มี sidebar และธีมนี้คือธีมมาตรฐานของ WordPress ซึ่งผมดัดแปลงแค่ในเมนูที่มีไม่ได้แก้โค้ด)

คำถามสุดท้ายที่ถูกถามคือเรื่องว่าผมบอกว่าใช้ HTML5 (จริงๆ ไม่ได้ใช้ HTML5 ถ้าพูดกันตามตัว standard เพราะผมลอง HTML5 Shim แล้วก็ยังไม่ได้ เลยว่าใช้ div ธรรมดา แต่คำนี้คนรู้จักมากกว่าถ้าจะพูดถึงการออกแบบเว็บสมัยใหม่ที่ใช้ div ไม่ใช่ table หรือ layer) กรรมการเลยเตือนว่าถ้าไปทำให้ลูกค้าต่อไปอย่าเอาเทคโนโลยีเป็นตัวตั้ง เพราะคนใช้งานบางคนไม่ได้อัพเดต browser ซึ่งตรงนี้ได้ยินคำว่า “อย่าเอาเทคโนโลยีเป็นตัวตั้ง” แล้วตะขิดตะขวงใจเพราะมันเหมือนบอกว่า “อย่าเอา best practice มาเป็นตัวตั้ง แต่ให้เห็นแก่ความ petdo ของ user” (Flash? แล้วโทรศัพท์หละ? Table? แล้วโค้ดจะอ่านยังไง?) ฉะนั้นเลยบอก “อ้น ขอ IE เปิดหน่อย” ปรากฎว่า IE เปิดได้ครับ ยกเว้น CSS overflow มันมีผลทั้งสองแกนทำให้ scrollbar หาย (ลืมเช็คตอนออก รีบเกินไป) และก็ shadow ไม่มี นอกนั้น IE แสดงผลได้ปกติ เป็นเครื่องยึนยันว่าเว็บผมไม่ใช่ว่า HTML5 อย่างเดียวแล้วจะยิง IE ทิ้งอย่างไร้ความปรานี

สิ่งที่พลาดไปตอน present ครับ คือการนำเสนอว่าทำไมต้อง tableless ต้อง no flash ต้อง no frame ซึ่งพวกนี้ผมว่าครูสอนทำเว็บตามโรงเรียนจะไม่เห็นความสำคัญกันเพราะถ้าจะทำพวกนี้ได้นักเรียนตายแน่เพราะ Tools ที่ใช้กันมันทำไม่ได้ง่ายๆ (ลองเอา android เข้าหน้ามี frame แล้วจะรู้ครับว่ามัน scroll frame ไม่ได้เพราะสิทธิบัตรการ scroll frame มันอยู่กับ Apple ส่วน Flash เอ่อ คงรู้ๆ กันดีว่า iOS ไม่มี Flash)

ผลปรากฎว่า ทีมที่ได้ที่ 1… Usability ห่วยขั้นเทพครับ เปิดมาภาพหัวเว็บยาวล้นจอ ตรงนี้ไม่ใช่ว่าแพ้แล้วจะมาเขียนโจมตีเขา เพราะทีมต้นกล้าก็เห็นด้วยกับผมว่าแค่ header ล้นจอมันก็เห็นแล้วว่าเว็บมันออกแบบมาแล้วใช้ไม่ได้จริงแค่ไหน สำหรับทีมอื่นๆ ที่ได้รางวัล ก็โอเคว่าเว็บพอใช้ได้ (ถึงจะไม่ได้นำสมัย) แต่มีการใช้ ​Flash วูบวาบ

“คนออกแบบเว็บน่ะมีสองประเภท ประเภทที่หนึ่งคือ Web Designer ที่มองเว็บไม่ใช่เป็นกราฟฟิคภาพหนึ่งแต่เป็น interactive ไม่ได้ว่าเว็บจะอยู่ตามที่ออกแบบตลอด เข้าใจเรื่อง Usability ส่วนอีกประเภทคือ Graphic Designer ที่มาออกแบบเว็บ เว็บอาจจะดูสวยกว่าเพราะภาพอลังการ แต่แน่หละเมื่อนำไปใช้งาน ความรู้สึกมันต่างกันนะ” — @manatsawin

[อ่านบล็อค @Fantasier](https://itongla.wordpress.com/2011/07/31/things-from-wmc3/)

ปล. ผมแนะนำว่า วิธีที่ยุติธรรมที่สุดคือเปิดเผยคะแนน หรือเขียนวิจารณ์ทีละเว็บ แบบ NSC ที่จะเขียนจุดเด่นด้อย คำแนะนำของกรรมการให้ในแต่ละรอบด้วย