วันพุธที่ 3 มิถุนายน พ.ศ. 2558

SQL Injection

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

SQL Injection คืออะไร

   คือช่องโหว่ที่เกิดจากการส่งผ่านข้อมูลจากผู้ใช้เข้ามายัง SQL Statement เพื่อสั่งให้ทำ คำสั่ง/เหตุการณ์ อื่นนอกเหนือจากสิ่งที่โปรแกรมเมอร์ต้องการ ยกตัวอย่างเช่น หากเราจะทำระบบล็อกอินเราก็ต้องรับค่า Username กับ Password ด้วยการเขียนโค้ดแบบนี้

หาก ผู้ใช้ ป้อนค่า
username เป็น ชื่อผู้ใช้ใดๆก็ได้ที่อยู่ในระบบ
password  เป็น  ' OR '1'='1
จะทำให้สามารถล็อกอินเข้าระบบเป็นใครก็ได้ทันที เนื่องจาก SQL Statement มีค่าเป็น
SELECT * FROM db_user WHERE username='[ชื่อผู้ใช้]' AND password= '' OR '1'='1';
เท่ากับว่าเงื่อนไขนี้เป็นจริงเสมอ

ในกรณีเลวร้ายสุดคือ ลบข้อมูลในตารางทิ้งซะเลย โดยการกรอกค่า
username เป็น ' OR '1'='1
password เป็น ' OR '1'='1' ; DELETE FROM db_user WHERE '1'='1
ทำให้ SQL String มีค่าเป็น
SELECT * FROM db_user WHERE username='' OR '1'='1' AND password= '' OR '1'='1' ; DELETE FROM db_user WHERE '1'='1' ;

ส่วนวิธีการแก้ไขปัญหาตรงจุดนี้ของ PHP แนะนำให้ใช้ Prepare Statement เข้ามาคลุม แล้วส่งค่าผ่านฟังก์ชั่น bindParam แทนที่การแทรกลงใน String ตรงๆ จากตัวอย่างดังกล่าวโค้ดจะมีหน้าตาประมาณนี้ครับ

ส่วนภาษาอื่นก็มีเช่นกัน สามารถค้นหาจากกูเกิ้ลโดยพิมพ์ในช่องค้นหาเป็น "[ภาษา] Prepare Statement"

วันศุกร์ที่ 1 พฤษภาคม พ.ศ. 2558

มาหัดใช้ Linq กันเถอะ

     วันนี้ผมมี เทคนิคการเขียนโปรแกรมภาษา C# มานำเสนอนั้นก็คือ Linq นั้นเอง แต่ก่อนจะเจาะลึกถึงเนื้อหาเรามารู้จักกันก่อนว่า Linq นั้นคืออะไร
     Linq คือ Syntax ที่พัฒนาโดยบริษัท Microsoft เพื่อตอบโจทย์ในการแปลงผลลัพธ์ของการ Query จากฐานข้อมูลมาอยู่ในรูปแบบ Object ได้ง่ายและสะดวกยิ่งขึ้น อีกทั้งรูปแบบ Syntax แทบจะเหมือนกับ SQL ทำให้เราสามารถค้นหาหรือจัดเรียงข้อมูลได้โดยการเขียนโค้ดเพียงไม่กี่บรรทัดเท่านั้น และในด้านการทำงานอาจเร็วและสะดวกกว่าการหาหรือจัดเรียงข้อมูลด้วย for หรือ foreach ได้อีกด้วย หากท่านใดอยากทราบข้อมูลทฤษฎีแบบเจาะลึกให้อ่านข้อมูลที่นี้ดูนะครับ

https://bithai.wordpress.com/2009/09/22/ทำความรู้จัก-linq-ตอน1/
https://bithai.wordpress.com/2009/09/22/ทำความรู้จัก-linq-ตอน2/

    ในส่วนของผมจะเจาะประเด็นไป Linq To Object เป็นหลัก เนื่องจากเป็นส่วนที่ใกล้ตัวมากที่สุดและน่าจะใช้งานบ่อยสุด โดยตัวอย่างโจทย์ที่ผมใช้มาทดสอบคือ

เรียงผลลัพธ์ข้อมูลใน int[] จากน้อยไปหามาก
โดยที่ รูปแบบ input เป็น
1000 , 9, 0, 5, 3, 7, 2, 1, 4 , 11 , 10 , 15 ,8 , 13 , 101 , 99 , 55 , 44 , 21 , 29 , 23 , 159 , 112 , 224
กรณีเปรียบเทียบคือ
   1. อัลกอริทึม Bubble Sort 
   2. อัลกอริทึม Binary Tree
   3. Linq
ซึ่งโค้ดที่ใช้ทดสอบมีลักษณะดังนี้ (ท่านสามารถนำโค้ดชุดนี้ไปรันได้บน Visual Studio)

สเป็คเครื่อง PC ที่ใช้ทดสอบคือ
Intel Core i5-2500K CPU 3.30 GHz
RAM 8 GB

ผลการทดสอบที่ได้คือ

  1. Bubble Sort ใช้เวลาประมาณ 0.1744 ms
  2. Binary Tree Sort (นับเฉพาะเวลา Traverse Node) ใช้เวลาประมาณ 0.2254 ms 
  3. Linq เรียกโค้ดให้ทำงานครั้งที่ 1 ใช้เวลาประมาณ 4.6618 ms 
  4. Linq เรียกโค้ดให้ทำงานครั้งที่ 2 ใช้เวลาประมาณ 0.0176 ms

สรุปผลการทดสอบ
    ในการทำงานของ Linq ครั้งแรก จะทำงานได้ช้ากว่า Bubble Sort หรือ Binary Tree Sort มาก เนื่องจากในการเรียกใช้งานครั้งแรก Syntax จำเป็นจะต้องถูกคอมไพล์ก่อน (Runtime Compile) แต่ถ้าหากเทียบกันกับการเรียกครั้งที่ 2 เราจะเห็นได้ว่า มันทำงานได้เร็วกว่า Bubble Sort กับ Tree Sort เกือบ 10 เท่า ในการเขียนโค้ดจะเห็นได้ว่า LinqOrderByAsc() จะมีจำนวนบรรทัดโค้ดสั้นที่สุดเมื่อเทียบกับ Bubble Sort หรือ Binary Tree Sort ก็ตาม

   หลังจากที่ผมได้ทราบผลการทดสอบ ผมก็ได้ทำการค้นคว้าข้อมูลต่อจนทราบวิธีแก้ไขความล่าช้าในการทำงานครั้งแรก มีอยู่ 2 วิธีที่ทราบคือ
   1. สั่งเรียกชุดคำสั่ง Linq ก่อนใช้งานจริงอย่างน้อย 1 ครั้ง
   2. นำคราส CompiledQuery  (มีในเฉพาะ .NET Framework 4.5 and 4.6 เท่านั้น) มาครอบชุดคำสั่ง Linq ซึ่งวิธีการเขียนโค้ดจะอยู่ใน 
http://www.codeproject.com/Articles/38174/How-to-improve-your-LINQ-query-performance-by-X

แล้ว Unity Engine ละใช้งานได้ไหม?
    ในส่วนของ System.Linq ใช้งานได้บน PC, Android  แต่จะมีปัญหากับการคอมไพล์บน iOS เช่น กรณีที่มีการใช้งาน OrderBy เป็นต้น  การแก้ไขเบื้องต้น คือ ติดตั้ง Asset : Linq To iOS (เสียเงิน) หรือ UniLinq (ฟรี) ก็จะทำให้โค้ดที่เราเขียนสามารถทำงานได้บน iOS ตามปกติครับ

วันอังคารที่ 28 เมษายน พ.ศ. 2558

สรุปการบรรยายจากคุณ Hiroyuki Tamura บริษัท tri-Ace

     เมื่อวันจันทร์ที่ 27 เมษายน 2558 ผมได้เข้าร่วมงาน Bangkok International Digital Content Festival ซึ่งเป็นงานเทศกาลดิจิตอลคอนเทนท์ที่ยิ่งใหญ่ประจำปี ในส่วนของงานนี้ผมได้มีโอกาสเข้าฟังการบรรยายของคุณ Hiroyuki Tamura จากบริษัท tri-Ace ซึ่งเป็นบริษัทผลิตเกมที่ใหญ่แห่งนึงของญี่ปุ่นและได้ฝากผลงานดังมากมายอาทิ Star Ocean, Phantasy Star, Valkyrie Profile เป็นต้น ในส่วนของคุณ Tamura เองได้อยู่ในตำแหน่ง Producer ของบริษัท ก็ได้มาเล่าถึงประสบการณ์และวิธีการทำงานที่สำคัญและน่าสนใจมากมาย ตัวผมเลยคิดว่าอยากจะบันทึกลงบล็อกไว้ให้ทุกท่านที่ไม่ได้มีโอกาสไปได้ทราบกัน โดยรายละเอียดหลักๆจะมีดังนี้ครับ

การพูดคุยกับบริษัทคู่ค้าเพื่อ รับ/เสนอ งาน

  • การเข้าไป Approach เพื่อ รับ/เสนอ งานต่างๆ ควรคำนึงถึงระยะยาวเป็นหลัก
  • การเข้าไป Approach เพื่อเสนอตัวงาน จะต้องนำเสนอ ธีม ให้เห็น อีกทั้งในเรื่องของความสนุกและค่าใช้จ่ายในการดำเนินงาน ก็ต้องแสดงให้เห็นด้วยเช่นกัน
  • หากมี Game Engine เป็นของตัวเองควรนำเสนอให้เห็น เพื่อแสดงจุดเด่นของบริษัท
  • หากการเข้าไป Approach เป็นในนามของ Developer ควรจะต้องระวัง ไม่สำคัญตัวเองมากจนเกินไป

การวางแผน

  • Planner จะทำหน้าที่เป็นผู้วางแผนการปฏิบัติงาน และประสานงานระหว่าง Programmer และ Artist 
  • เมื่อ Planner ได้รับผลการประเมิณเวลาในการปฏิบัติงานของ Programmer และ Artist แล้ว จะต้องทำการเผื่อเวลาเพิ่มอีกเป็น 1.5 เท่า
  • เมื่อ Planner สรุปแผนงานและเวลาเรียบร้อยแล้ว ในขั้นสุดท้ายควรแจ้งให้กับทาง  Programmer และ Artist ทุกคนทราบ
  • ความแม่นยำในการวางแผนและดำเนินการเป็นสิ่งสำคัญมากในสมัยนี้  ไม่สามารถล่าช้า 3 เดือน หรือ 6 เดือนเหมือนแต่ก่อนได้อีกต่อไป

การเซ็นสัญญา

  • หากเป็นแผนระยะยาว ควรบอก จุดด้อย/จุดแข็ง (รวมทั้งสิ่งที่ทำได้และไม่ได้) และความเสี่ยงต่างๆ ของบริษัทให้ชัดเจน ห้ามโกหกเด็ดขาด
  • การรายงาน Process ควรแจ้งผลการดำเนินงานเป็นระยะให้ทางบริษัทคู่ค้าทราบ ห้ามปล่อยว่างเด็ดขาด
  • หากรายละเอียดของสัญญาเป็นนามธรรมมากๆ ควรจะต้องพูดคุยให้ดีก่อนเซ็นสัญญา เช่น 40% ของความก้าวหน้ามีรายละเอียดอะไรบ้าง เป็นต้น

  การสร้างทีม

  • Director มีหน้าที่ควบคุมคุณภาพงานโดยรวม ทั้งด้าน Technical และ Quality
  • Producer มีหน้าที่ในการวางแผนการดำเนินงาน และวางแผนในด้านเงินทุน
  • Head Programmer หัวหน้าหรือผู้นำในด้าน Programmer
  • Head Artist หัวหน้าหรือผู้นำในด้าน Artist
  • Team Leader จะต้องประเมิณเผื่อในเรื่องของการลาออกของคนในบริษัท ในอนาคต เนื่องจากพนักงานในอุตสาหกรรมนี้มีโอกาสที่จะลาออกได้ อาจต้องเตรียมการในเรื่องของ Outsource เผื่อเอาไว้แต่เนิ่นๆ 
  • การประเมินในด้านจำนวนพนักงานในทีมควรเผื่อไว้ประมาณ 10 - 20% ของกำลังคนที่ต้องการ
การดำเนินงาน
  • พนักงานในทีมควรเขียน Report ประจำวันส่งหัวหน้างานให้ทราบ
  • การแจ้ง Milestone ควรติดไว้ตรงจุดที่ทุกคนมองเห็นได้ง่าย เช่น บอร์ด, พื้นหลังหน้าจอคอม เป็นต้น
  • ควรมีการรักษา Motivation ของพนักงาน ด้วยการพาไปเที่ยว ทานข้าว  ให้กำลังใจ เมื่อมีโอกาส
  • หากมีการเร่งเวลาการดำเนินงานจากบริษัทคู่ค้า จะมีอยู่ 2 วิธีในการจัดการคือ ลดจำนวนคอนเทนต์ลง กับ เพิ่มจำนวนพนักงาน

 

วันเสาร์ที่ 25 เมษายน พ.ศ. 2558

จะเขียนโค้ดบน Unity เชื่อมต่อกับ Server ได้อย่างไร

    หลายคนคงสงสัยกันไม่น้อยว่า เกม/แอพ ที่เขียนมาจะทำไงให้คุยกับ เซิฟเวอร์ได้ เล่นออนไลน์ได้ เล่นพร้อมกันหลายคนในเวลาเดียวกันได้ หรือเก็บข้อมูลเอาไว้บนฐานข้อมูลของเซิฟเวอร์ ซึ่งวันนี้ผมจะอธิบายเรื่องนี้ให้ฟังกันครับ โดยจะขอแบ่งออกเป็น 2 หัวข้อดังนี้

1. การเชื่อมต่อผ่าน Web API หรือ Web Service

     ตัวอย่างกรณีใช้งานจริงจะเป็นในรูปแบบ เกม / แอพ (ไคลเอนต์) เรียกใช้งาน Web API ที่อยู่บน เซิฟเวอร์  ในการเขียนโค้ดจริงฝั่งไคลเอนต์ (Unity) จะต้องเรียก Web API ผ่านคราส WWW  ส่วนฝั่งเซิฟเวอร์ จะเขียนเป็น Web API ด้วยภาษาใดก็ได้ ครับ

ตัวอย่าง โค้ดฝั่งไคลเอนต์ (Unity C#)

ตัวอย่าง โค้ดฝั่งเซิฟเวอร์ myapi.php (ภาษา PHP และฐานข้อมูล MySQL)

       ข้อดีของวิธีนี้คือ ประหยัดทรัพยากรเครื่องเซิฟเวอร์ เพราะไม่จำเป็นต้องเชื่อมต่อกับไคลเอนต์ตลอดเวลา ข้อด้อยคือ ไม่รองรับกับการเขียนแอพแบบเรียลไทม์ ในกรณีที่บางเวลาเซิฟเวอร์จำเป็นต้องส่งข้อมูลบางอย่างแบบทันทีทันใดไปยังไคลเอนต์ เช่น ระบบแชทแบบเรียลไทม์ , เกมที่มีการตอบสนองแบบเรียลไทม์ (ผู้เล่นมีการรับรู้การเปลี่ยนแปลงของคนอื่น ในเวลาเดียวกัน)

2.การเชื่อมต่อผ่าน Remote Procedure Call (RPC)

     การเชื่อมต่อจะเป็นในลักษณะแบบ Peer-to-Peer อาจอยู่ในรูปแบบ ไคลเอนต์ กับ ไคลเอนต์ หรือ ไคลเอนต์ กับ เซิฟเวอร์ ก็ได้ เท่าที่ผมทราบ Library ที่ใช้ในการพัฒนามีดังนี้ (แต่ปัจจุบัน อาจมีมากกว่านี้แล้ว)
ตัวอย่างโค้ด สามารถดาวน์โหลด ได้ที่ บทความ  PROJECT: SURVIVAL SHOOTER MULTI-PLAYER

       ข้อดีของวิธีนี้คือ การตอบสนองของตัวเกม / แอพ เป็นแบบเรียลไทม์ ข้อด้อยคือ ใช้ทรัพยากรเครื่องเซิฟเวอร์มากกว่า วิธีแรก เนื่องจากต้องเชื่อมต่อตลอดเวลาในขณะที่เล่น

สรุป

      ทั้ง 2 วิธี มีข้อดีและข้อด้อยแตกต่างกัน ทั้งนี้ผู้พัฒนาจะต้องเลือกตามความเหมาะสมของตัว เกม / แอพ ด้วย เพราะมิเช่นนั้นแล้วเราอาจต้องเสียค่าใช้จ่ายในการพัฒนา มากกว่าที่ควรจะเป็นครับ

วันพฤหัสบดีที่ 2 เมษายน พ.ศ. 2558

เปิดบล็อกแล้วจ้า

 เกริ่นนำ

วันนี้ได้ฤกษ์งามยามดี เหมาะแก่การเริ่มสร้างบล็อกของตัวเองเสียที หลังจากที่อ่านความรู้จากคนอื่นมาเยอะ บวกกับชั่วโมงบิน (ทำงาน) สูงพอควรแล้ว ซึ่งคิดว่าความรู้ของตัวเองก็น่าจะมีประโยชน์กับผู้อื่นได้บ้าง  อีกเหตุผลนึงคืออยากทำเอกสารความรู้ต่างๆจากประสบการณ์ทำงาน ไว้ให้กับตัวผมเองเมื่อในยามที่ต้องการใช้งานมัน เอาเป็นว่า วินๆ กันทั้งผู้อ่านและผู้เขียน กันเลยละครับ (ฮ่าๆ)  ยังไงก็ขอฝากเนื้อฝากตัวด้วยนะครับ

ประสบการณ์การทำงานละ?

ก่อนอื่นผมต้องบอกก่อนว่าตัวผมเองเป็น โปรแกรมเมอร์ ด้านเกม มา 6 ปี เริ่มตั้งแต่ทำเว็บเกมสำหรับ Feature Phone ด้วยภาษา PHP จนกระทั้งทำเป็น App ลงมือถือระบบปฏิบัติการ Android , iOS ด้วย Unity Engine (C#) ต้องบอกได้เลยว่าการทำเกมให้เสร็จได้นั้นไม่ใช่เรื่องง่ายอย่างที่คิด ต้องพบอุปสรรคหลายอย่าง มีสมหวังบ้างผิดหวังบ้างปนๆกันไป ส่วนเหตุผลในการตัดสินใจมาทำงานด้านนี้ คือผมเป็นคนที่ชอบเล่นเกมมาตั้งแต่เด็กแล้วและมีความฝันที่จะอยากทำเกม และนั้นคือเป็นจุดเริ่มต้นที่ทำให้ผมมาทำอาชีพนี้นั้นเอง

ผู้อ่านจะได้ประโยชน์อะไรจากการอ่านบล็อกนี้?

ทุกท่านที่เข้ามาอ่านบล็อกนี้ จะได้รับประโยชน์ในเรื่องของเทคนิคการเขียนโค้ด ภาษา PHP, SQL, C# และ Java รวมทั้งการใช้งาน Unity Engine ที่กำลังฮิตในขณะนี้ด้วย  ซึ่งผมตั้งเป้าไว้ว่าจะทยอยเขียนให้อ่านอย่างน้อยเดือนละ 1-2 เรื่อง นะครับ โดยจะเน้นเนื้อหาที่เป็นส่วนต่อยอดจากพื้นฐานเป็นหลักสำหรับการทำงาน หรือท่านใดอยากแนะนำให้ลงเนื้อหาเรื่องใดเป็นพิเศษ ลงหัวข้อไว้ที่คอมเม้นท์ได้นะครับ