PHP: Lock File ไม่ให้คนอื่นมาอ่านหรือเขียน

การ lock file ใน php ทำเพื่อป้องกันไม่ให้คนอื่นมาอ่านหรือเขียน ในขณะที่เรากำลังอ่านหรือเขียนอยู่ โดยเราจะใช้ function ที่ชื่อว่า flock ตัว flock จะเป็นตัวจัดการว่ามีคนอ่านหรือเขียน file นี้อยู่หรือไม่ ประโยชน์ของมันคือการเขียนทีละครั้งจะทำให้ข้อมูลไม่เกิดข้อผิดพลาดกรณีที่ write 2 ตัวพร้อมกันและข้อมูลไม่เหมือนกันครับ แต่โทษของมันคือการ deadlock คือหากเราลืม unlock หรือไปไม่ถึงขั้นนั้นจะทำให้คนอื่นๆเขียนไม่ได้เช่นกันครับ

รูปแบบ Function flock()

boolean flock(file_resource handler,int operation,int &wouldblock);

อธิบายง่ายๆคือ

  • file_resurce คือตัวแปรที่มาจาก fopen อ่ะครับ
  • operation จะเป็นค่าคงตัวซึ่งเค้ากำหนดมาดังนี้ครับ
    LOCK_SH คือ ไม่ให้คนอื่นอ่าน
    LOCK_EX คือ ไม่ให้คนอื่นเขียน
    LOCK_UN คือปลดล็อค (แต่ถ้าใช้ lock ผมว่ามันกันได้ทั้งอ่านและเขียน)
    LOCK_NB คือบอกว่าไม่อนุญาติให้คนอื่นใช้งานตอนล็อคอยู่ทันที(ถ้าไม่ใส่ตัวนี้ คนอื่นจะรอจนกว่าจะ unlock ถึงจะอ่านเขียนได้ แต่ถ้าใส่จะ return false ทันที
  • wouldblock ไม่ทราบครับ ผมไม่ใช้

return ค่าเป็น true หากล็อคได้ และ false ถเาล็อคไม่ได้

ตัวอย่างการใช้

<?php 
$fp = fopen("lock.txt", "w+");
if (flock($fp, LOCK_EX | LOCK_NB )) { 
    ftruncate($fp, 0); // truncate file 
    fwrite($fp, "Write heren aaa adsasd \n"); 
    fflush($fp); // flush output before releasing the lock 
    sleep(10); 
    flock($fp, LOCK_UN | LOCK_NB ); // release the lock 
} else { 
    echo "Couldn't get the lock!"; 
} 
fclose($fp); 
?>

จาก code นี้ถ้าสั่งเรียก file นี้ 2 ครั้งติดๆกันจะเห็นว่าครั้งที่ 2 จะขึ้นว่าไม่สามารถ lock ได้ครับ

บันทึกความหลัง กว่าจะมาเป็นตัวเองในตอนนี้

อันนี้เป็นบันทึกวีรกรรมต่างๆที่เคยทำไว้ จนมาเป็นคนที่พอมีความรู้เรื่องคอมและเขียนโปรแกรมเป็น ณ ตอนนี้

ผม เริ่มรู้จักการเขียนโปรแกรมครั้งแรกตอน ป.4 ตอนนั้นพ่อไปได้ VB 6.0 กับเอกสารมาจากไหนไม่รู้ แล้วได้มาแรกๆก็เห่อครับ ลองเล่นๆไปเรื่อยๆ จำได้ว่าตอนนั้นเก่งสุดคือเปลี่ยน Form ให้เอา Form อื่นๆขึ้นมาแสดงได้ แล้วก็ลอก Code แบบลองผิดลองถูกมาได้ตรวจรหัสว่า ค่าใน Textbox ถูกไหมก่อนเปลี่ยนไป Form อื่นได้ ได้แค่นั้นก็เลิกเห่อแล้วกลับไปเล่นเกมส์ต่อ ตอนนั้นเล่นพวก RA2 Yuri Starcraft LionKing มั้ง จนมาเริ่มเขียนโปรแกรมอีกทีตอน ป.6 เขียนอยู่ 3 วัน ได้ความรู้คืนมาก็เลิกเพราะต้องอ่านหนังสือสอบเข้า ม.1 รู้สึกตอน ป.6 เอา Window 2000 ไปลงใส่เครื่องกากในห้องเรียนที่มี ram 48mb ด้วย(จริงๆจะลง xp แต่ ram ไม่ถึง) แล้วก็ใช้ remote anything หรืออะไรเนี่ยแหละ(ที่เป็น Master เป็นรูปพระอาทิตย์ Slave คล้ายๆ ห่วงยาง) แกล้งคนที่ห้องสมุดด้วยล่ะ ปีนี้รู้จัก Linux ครั้งแรก เพราะเห็นจากเครื่อง Server ห้องสมุด ใช้ Hidden เป็นปีนี้ และปีนี้ก็โดนจับได้ว่าซ่อนเกมส์ไว้นเครื่องบรรณารักษ์ ตอนที่รู้คือวันที่ผมไม่ได้ไปแล้วเหมือนเครื่องมีปัญหา อาจารย์เลยตามน้องมาดู เจอเกมส์เพียบ 555 ไม่น่าโดดเลยวันนั้น จริงๆจบออกมายังไม่ได้ลบเกมส์เลย ปีนี้เริ่มสนใจ PHP Nuke มาก เอามาลองๆทำว่าจะทำเว็บเองสักหน่อย แต่ก็ไม่ได้ ไม่รู้จะทำเว็บอะไร

ผม เข้าเรียน ม.1 ที่โรงเรียนกาญจนาภิเษกวิทยาลัย นครปฐม ผมเป็นพวกชอบเพ้อ ปกติผมสามารถนั่งเฉยๆเป็นชั่วโมงได้โดยไม่รู้สึกเบื่อเป็น skill ที่ใช้ในเวลาเรียนเลยทีเดียว วิชาไหนน่าเบื่อผมก็ไม่ได้ฟังอะไรเลยนั่งเพ้อไปเรื่อยๆ ปกติผมเพ้อก็ประมาณคล้ายๆแต่งนิยายในหัวอ่ะครับ(ไม่อยากพูดว่าปัจจุบันผมก็ ยังเป็นอยู่ ถ้าเห็นผมนั่งเฉยๆคือแต่งนิยายในหัวอยู่) แต่เนื้อหาซ้ำๆกัน แต่ก็เปลี่ยนได้เรื่อยๆขึ้นอยู่กับการ์ตูนที่ดูหรือ่านในช่วงเวลานั้นครับ ซึ่งอันนี้เป็นนิสัยที่ผมทำตั้งแต่อยู่ชั้นประถม ถามว่ามีประโยชน์ไหม ผมว่ามันมีประโยชน์คือใช้หัวบ่อยๆ ไม่ว่าจะเป็นตอนเรียน นั่งรถ บลาๆ ทำให้สมองฝึกคิดตลอด ทำให้ผมคิดว่าผมเป็นคนที่คิดแก้ไขปัญหาบางอย่างได้ไวขึ้น ตอนเข้ามาโรงเรียนนี้ปีแรก ไม่มีอะไรเลยครับ ผมก็ไม่ได้เก่งมากแค่ขโมย Tools ของพี่ Hack เครื่องอาจารย์กับเครื่อง Server ที่เป็น Windows 2003 ได้แค่นั้นเอง แต่ทำไรต่อไม่ได้เพราะความรู้มีแค่ใช้ Tools เป็น(แต่ไม่หมดเลยเข้าไปควบคุมณขณะนั้นได้ แต่วาง backdoors ยังไม่เป็น) ซึ่งตอน Hack เนี่ย Tools มันทำงานบน CMD ทำให้ผมต้องฝึก CMD ความรู้ที่ได้รับณขณะนั้นคือ cd dir copy ping ครับ และก็ช่วงนั้นเน็ตที่โรงเรียนช้ามาก ผมเลยไม่ค่อยได้ทำอะไรมากส่วนมากก็ Scan Port แล้วก็ใช้ LAN Survey พยายามดูโครงสร้าง NetWork ไปเรื่อยๆ ปีนี้ผมเริ่มสิงบอร์ดของ Thaiware  ซึ่งเป็นเว็บบอร์ดแรก และบอร์ดเดียวในช่วงนั้นที่เล่น โดยใช้ Display Name ว่า MIX THE WIZARD รู้สึกมาจากบ้าหัวขโมยแห่งบารามอสช่วงนั้นเลยเอาชื่อตัวเองใส่ THE WIZARD ตามหลัง ตอนนั้นบอร์ดคึกคักมากเฝ้าได้ทั้งวันเลยทีเดียว และก็เริ่มสูบความรู้ Programing กับแก้ปัญหาคอมเบื้องต้นจากที่นั่น(อ่านแม่มทุกกระทู้เกียวกับผมเปล่าไม่สน อ่านอย่างเดียว) ปีนี้เริ่มลองเขียน C แล้ว โดยฝึกจาก Thaiware  และ Programming.in.th แล้วสักพัก็เลิกไปเพราะบางข้อยากเกินไป ทำไม่ไหว (จริงๆหลายข้อเลย)

พอ ขึ้น ม.2 วิชาเริ่มแก่กล้า เริ่มใช้ net send เกรียนชาวบ้านเค้าเป็นและ ก็จัดไปเกรียนแม่ม คำสั่ง net send นี้บน Windows XP( Win 7 ขึ้นไปรับไม่ได้แล้ว) สามารถสร้าง Message Box ขึ้นไปแสดงในเครื่องเป้าหมายได้ จริงๆรู้ก่อนหน้านี้แต่จำไม่ได้ว่ารู้มาช่วงไหน แต่จำได้ตอนอยู่ดีมีเพื่อนส่งมันมาก่อน เลยส่งกลับไปสนุกดี 555+ ปีนี้เครื่องบ้านผมโดน Bontrok หรืออะไรเนี่ยแหละไอ้ไวรัสสร้าง Folder แบบเนียนๆจู่โจม ทำให้ทั้งโรงเรียนวุ่นไปหมด แล้วผมก็เสนอแก้ให้อาจารย์ด้วย HijackThis และ ComboFix ซึ่ง Tools พวกนี้ได้มากจาก Thaiware แล้วรู้สึกจะได้ EBook เกี่ยวกับ Registry มาเล่นนึงก็เลยเอาพวกไวรัส Hacked By Godzilla หรืออะไรนี่แหละที่เป็น vbs มาศึกษาแล้วพยายามลองเขียนไวรัสด้วยตัวเอง แต่สุดท้ายก็ดองไว้เพราะไม่รู้จะทำไปทำไม ช่วงนั้นผมแก้ไวรัสอะไรได้เก็บไว้ใน FlashDrive หมดเลย เอาไว้แกล้งคน ตอนนั้นไวรัสในโรงเรียนมีตัวเดียวที่ผมเห็นว่าติดแล้ว format เถอะครับ คือ mosquite.exe(ชื่อไม่ตรง แต่ประมาณนี้ รู้สึกชื่อจริงมันสั้นกว่านี้นะ) คือมันทำให้คลิกขวาไม่ได้ แล้วช่วงนั้นผมใช้ TrueCrypt เข้ารหัส Flash Drive เจอตัวนี้ผนึกการทำงานของ Tools ผมหมดเลย แก้ไม่ได้เพราะ  Safe Mode ก็เข้าไม่ได้ด้วย จบเลยตัวนี้ นอกนั้นแทบจะเข้า Safe Mode แล้วแก้ได้หมด ต่อมาได้แผ่น WinPE(Windows Portable Edition) มาใช้ ตอนนั้นใช้แผ่นที่ชื่อ AugiePE เป็นแผ่นที่ดีมาก เพราะแค่แผ่นเดียวแก้ได้เกือบหมด ปีนี้ผมแทบเดิมไปแก้ห้องหมวดเกือบทุกหมวดในโรงเรียนเลยทีเดียว ไวรัสเพียบ

พอ ขึ้น ม.3 ปีนี้ผมก็ยังแก้ปัญหาคอมให้หมวดต่างๆอยู่ ทั้ง Hardware และ Software ปีนี้เก็บ Exp จนเวลอับหลายเวลเลย จริงๆผมไม่ค่อยชอบเรื่อง Hardware เท่าไหร่ เพราะไฟมันชอบดูด + ผมถอด CPU ไม่ได้ ใส่ RAM ไม่ได้(ปีนั้นผมกลัวมาก กลัวว่ากดๆไป Mainboard จะหัก 555) เดี๋ยวนี้ใส่ RAM เป็นแล้วแต่ยังถอด Heatsink CPU ไม่เป็นสักที ปีนี้ผมก็เริ่มเก่งกล้าขึ้นด้วย Hijackthis ช่วยดู Log ให้คนใน Thaiware บ้างอะไรบ้าง เริ่มกลับมาเรียน Programming อย่างจริงๆจังๆบ้างแล้ว โดยทำพวก Java นิดหน่อยแล้วเลิกเหมือนเคย ปีนี้ไม่ก็ตอนปีก่อนหน้ารู้สึกผมจะไปเข้าค่ายยุวคอมพิวเตอร์ ซึ่งสอนเขียนโปรแกรมด้วยภาษา Delphi ก็สนุกดีครับ เป็นค่ายที่ดีมาก เมื่อเร็วๆนี้ก็เปลี่ยนมาสอน C# แทนแล้ว ดูเป็น OOP และทันสมัยมากขึ้น รู้สึกโปรเจคที่ผมทำเป็นเกมส์หยิบขวดนั้น แต่ตอนไป Present ดันเอาตัว Bug ที่แสดงคนชนะกับแพ้สลับกันขึ้น Present อย่างอาย 555 แต่ได้ Poppular Vote หล่ะ รู้สึกปีนี้ผมจะเริ่มเอนเอียงไปทาง WebApp ด้วยคือไปทาง PHP ต้นเหตุคือมีพี่คนนึงรู้สึกจะชื่อพี่ตั๊กเมลถ้าจำไม่ผิดมีคำว่า MyDreamWhite ทำโปรเจคคล้ายแบบประเมินเด็กผ่านเว็บ จำได้ว่าช่วงนั้นผมลองไปตอบแบบทำ sample เกรียนๆให้ดู แล้วเค้าก็ add msn มาถามซึ่งบอกตามตรงเลยว่าตอนพี่เค้าถามนั่นแหละครั้งแรกที่จับ PHP ตอนนั้นเปลี่ยนจาก Appserv มาใช้ XAMPP ใหม่ๆเองมั้ง ช่วงแรกเอา CMS มาเล่นตอนประถม ผมก็แถๆไปด้วย จำได้ว่าโหลด PHP Document แบบ CHM มาเลยทีเดียว สมัยนั้นเป็นช่วงแรกที่เขียน PHP แบบเค้าให้ Code มาต้องไปอ่านกันเลยทีเดียวว่า Function ไหนใช้ทำอะไร แล้วใช้ phpMyAdmin เขียน SQL แล้วลองดูผลเองด้วย จำได้ว่าช่วงนั้นไปแก้ Code เค้าให้เกรียนขึ้น ปกติเดี๋ยวนี้เวลาเรียกแถวทั้งหมดใช่ while($row=mysql_fetch_assoc($res)) { .. } แต่ตอนนั้นผมไปแก้เป็นแบบนี้ครับ for($i=0; $i<mysql_num_rows($res);$i++){ $row = mysql_fetch_assoc($res); … } หรืออาจจะใช้ mysql_result เลยทีเดียวช่วงนั้นยังไม่ค่อยแม่มเรื่อง array ก็ที่อังกฤษพอถูไถได้ก็ช่วงนี้แหละ ต้องอ่านอังกฤษตลอดเลย แต่ก็ทำไปจนจบของพี่เค้าก็รู้สึกว่า PHP นี่มันสุดยอดใช่เลย กรุต้องมาแนวนี้แหละ 555

พอขึ้น ม.4 ปีนี้เริ่มมีการแข่งให้เงินแล้ว ตั้งแต่ Excel Access บลาๆ ยันแข่งเขียนโปรแกรมกันเลยทีเดียว แต่เขียนโปรแกรมได้อย่างมากที่ 3 เพราะไม่เก่งพอ ปีนี้ถ้าจำไม่ผิดเริ่มมาจากเริ่มกลับมาเล่น  ragnarok เถื่อน แล้วเห็นแนวโน้มว่าโปรขุดนี่มันยอดจริงๆ จึงทำโปรขุดขึ้นเอง ในขณะที่โปรขุดคนอื่นเป็นแบบ .exe เราทำเป็นเว็บ เปิดฟรีกิน Ads ครับ ได้มา 1000 กว่ามั้งครับจาก thaibuzz หรืออะไรเนี่ยแหละ ตอนนั้นเว็บที่ทำคือ mixproject.net ครับ ตอนแรกเขียนเอง ตอนหลังใช้ PHP-Fusion เป็นฐาน เนื่องจากเปิดให้ใช้ฟรี + โปรโมทเว็บลงในข้อความทุกข้อความ ผลที่ได้คือ ประมูลแบน IP Server ครับจะไม่มีภาพมาให้ขุดครับ ตอนนั้นกำลังคิดทำ V.2 ให้เป็น ajax พอดีด้วย V.2 ของผมเลยเป็น พวกแกอยากใช้ ไปหา Proxy มาสิ ข้าขุดผ่าน Proxy ให้ ก็ใช้ได้ในระดับนึง แต่ช้า จนในที่สุดก็ต้องปิดไปโดยปริยาย 55 เปลี่ยนมาทำ ishare.in.th แบบที่เห็นในทุกวันนี้(จริงๆเว็บตายตอน ม.5 มั้ง แล้วหลังจากนั้น domain ก้ล้าง) ต้องขอบคุณ BoomZKung (AliceSenzeXZ หรือ SenaSenzeXZ มันมีหลายชื่อ) ที่ให้ Host มายืมฝึกฝีมือจนผมเป็นผมในวันนี้ รู้สึกปีนี้มั้งไม่ก็ปีหน้าที่พี่ผมพี่ภูแนะนำให้ทำงานพิเศษที่ปัจจุบันก็ ยังทำอยู่(มีออกไปรอบนึงมั้ง แล้วกลับมาทำใหม่ ) เป็นงานเกี่ยวกับเว็บอ่ะ ไม่ยากแก้ PHP+Wordpress HTML+CSS  ไปเรื่อยๆ จากไม่เก่ง Javascript เป็นใช้งานมันได้ก็มาจากงานนี่แหละ ใช้ JQuery เป็นก็เพราะที่นี่ด้วย CSS จากที่ไม่อยากจับก็มาจับเพราะงานนี่อีกแหละ

พอขึ้น ม.5 ก็เหมือนเดิมไปแข่งๆๆๆ แต่ปีนี้เริ่มเก่งมาบ้างไปที่ไหนอย่างน้อยก็ชมเชย มากสุดคือที่ 2 ทำโปรขุดประมูลอีกแหละ คราวนี้ไม่ทำเว็บแล้วทำเป็น Java ไม่อยากพูดว่าโปรขุดนี่มันฝึกตัด String ชัดๆ สนุกมาก แล้วก็เริ่มทำโปรแกรมดูดการ์ตูนมาเก็บในเครื่องด้วย ถ้าจำไม่ผิด thaimanga.net ล่ะมั้ง เป็น VirtualMachine ช่วงนั้น VMWare เถื่อนอยู่ ตอนแรกดักลิงค์ดุดตรง สักพักมันเแปลี่ยนไปใช้เอาภาพใส่ Flash ไม่มีปัญหา ดูดมาหา Jpeg จาก FFD8 กับ FFD9 มั้ง (จำได้ว่าช่วงแรกเขียนผิด เป็นเอารหัสเริ่มกับหยุดตัวเดียวกันก็ว่าทำไมภาพมันดูไม่ครบส่วน) เป็นรหัสเริ่มกับหยุดของมันแล้วเอาเฉพาะส่วนนั้นออกมาแยกเป็น File ง่ายๆ ต่อ แล้วสักพักมันก็เอา Flash ไปเข้ารหัสหนีอีก ซึ่งก็ไม่มีปัญหา ใช้ VMWare กับโปรแกรม C# ที่สร้างขึ้นเอง ทำการเปิดเว็บ ทำเป็น Proxy จากนั้นก็ทำ JS สำหรับเปิดหน้าเปลี่ยนไปเรื่อยๆ Proxy ก็ดูว่าโหลด File Flash เสร็จยัง ถ้าเสร็จก็ Cap จอ จากนั้นก็ตัดเอาเฉพาะส่วนที่เป็นหน้าเก็บไว้(กว้างยาว เท่าเดินเกือบทุกหน้า) อันนี้ฝึกการคิด + สนุกมาก เป็นงานเด่นของปีนี้เลยทีเดียว เพราะโปรขุดนับแต้มด้วย Java ไปไม่รุ่งเวอร์ชั่นแรก เวอร์ชั่นนับแต้มหายก่อนได้ออกมั้ง เพราะขี้เกียจพัฒนาแล้วมาดูดการ์ตูน ปีนี้ว่าจะทำแข่ง NSC ก็ไม่ได้ทำ เพราะ Format เครื่องลืม Backup เงิบเลยทีเดียว อ้อปีนี้สอบ สอวน ด้วยแต่ไม่ผ่าน เจอเลขล้วนตายห่าเลย

พอขึ้น ม.6 ไฟเริ่มมอดและ ปีนี้ก็จำได้แต่ไปแข่งหลายๆที่เท่านั้นเอง ก็แข่งลาดกระบังก็ได้ที่ 1 มาที่แค้นมากคือจะคำว่า information_schema ไม่ได้ เลยทำข้อนั้นไม่ได้ นั่งเล่น gbrainy อย่างสนุกสนานเลยทีเดียว แต่ได้ที่ 1 นะ โจทย์ปีต่อมาก็คล้ายๆปีนั้นเพราะผมออกเอา reuse หมดเลย ปีนี้แข่ง NSC ด้วย น้ำท่วมเผาเต็มอัตราสูบ แต่ก็ได้แค่ 3000 เพราะทำ DOC ไม่เก่ง ผมทำโปรแกรมคล้ายๆกับตัวที่เอาไว้ลงโปรแกรมให้เครื่องที่ลงโปรแกรมนี้ใน ปริมาณมาก(จริงๆมี Bug อยู่แต่ช่างมันเพระาเผาไม่ทัน) คือมันจะดูดตัวลงกับวิธีการว่าเรากดเมาส์ตำแหน่งไหนบ้างกดปุ่มอะไรบ้างแล้ว ส่งเป็นขั้นตอนไปให้ Client ใช้ลงโปรแกรม ซึ่งผมทำ Doc ไม่เก่ง กรรมการเลยไม่เข้าใจว่าโปรแกรมผมต่างจาก Ghost ยังไง คือผมจะทำโปรแกรมที่ลงโปรแกรมเพิ่ม ไม่ใช่ลงใหม่ทั้งหมด ด้วยวิธีการนี้การปลด DeepFreeze ทุกเครื่องก็ทำได้ แต่ Doc ไม่เก่ง + มารู้ทีหลังว่า โปรแกรมที่ Write ส่งเป็นตัวที่มี Bug อยู่ (write ผิด file) ก็เงินเลย ช่างมันได้ 3000 ก็พอและ

ช่วงรอยต่อระหว่าง ม.6 ขึ้นปี 1 ก็ไม่มีอะไรมาก GAT PAT ONET ได้เกิน mean เกือบทุกวิชา พวกที่ต้องใช้อย่าง PAT1 ไรพวกนี้เกิน mean หมด แต่ GAT1 ไม่เต็ม เพราะคิดมากเกิน แน่นอนว่าได้ GAT2 มาช่วย ทำให้คะแนนพอๆกับคนได้ GAT1 เต็มใน โรงเรียนเลย (รู้สึก GAT2 ได้ 199.96) ตอนมาสอบลาดกระบังนี่ก็ชิวอังกฤษไม่อ่านเพราะผมไม่จำ Grammar เลขก็อ่านเล่มเดียว เป็นสรุป PAT1 เล่มสีเขียวบางๆอัดสูตรเข้าไป ส่วนคอมก็ไม่อ่าน พอผ่านก็จบครับ ไม่ดิ้นรนอีกเลย ชิวๆไปเรื่อยๆ

พอยาวไปและ อัตตชีวประวัติผม

บันทึกเข้าค่ายยุวคอมที่โรงเรียนสตรีศรีสุริโยทัย

ก็เกริ่นก่อนค่ายยุวคอมเนี่ยเป็นค่ายที่จัดมา 8 ปีแล้วมั้ง เป็นค่ายคอมค่ายแรกที่ผมได้ไปเข้าเลย สมัยผมเข้ายังสอน Delphi อยู่เลย แต่เมื่อประมาณ 2 ปีที่แล้วเปลี่ยนมาสอน C# โดยมากค่ายนี้จัดขึ้นช่วงเดือนตุลาคม ปีนี้คือ 1-5 ตุลาคม แต่ก็แล้วแต่ศูนย์ที่จัดด้วยครับ ปีนี้(และคิดว่าทุกๆปี)ผมจะเข้าไปเป็นพี่เลี้ยงของค่ายที่จัดที่โรงเรียน สตรีศรีสุริโยทัยครับ ปีนี้ผมเข้าไปช่วงเย็นของวันที่ 4 ตุลาคม(เกือบวันสุดท้าย) เพื่อไปช่วยน้องเค้าทำโปรเจคครับ ขอบอกตามตรงเลยว่าโปรเจคปีนี้ของน้องค่ายไม่ค่อยน่าสนใจส่วนมากเป็นแค่คลิกๆ แล้วแสดง กอปข้อมูลในเน็ตมาแปะๆ มันเลยดูไม่ค่อยน่าสนใจเท่าไหร่ แต่บางกลุ่มก็ทำยากเว่อร์เลย อย่างโปรแกรมจองตั๋วภาพยนต์ที่ออกแบบไว้หรูมาก แต่ทำตามจริงไม่ได้ทั้งหมด เพราะบางส่วนมันยากขนาดว่าผมยังต้องคิดนานเลย คือเค้าแบ่งเป็นวันได้ + มาแนวสายถึงปุ่ม 50 กว่าปุ่ม กลัวทำไม่ทันเลยปรับๆออกบ้าง โปรเจคน่าสนใจปีนี้คือเกมส์อาจารย์พูนศักดิ์ทะลุมิติ เพราะเป็นเกมส์ที่ถ้ามองแบบ marketing ในค่ายก็ดีคือทุกคนรู้จักและทำให้น่าสนใจได้ดี ถ้าถามว่าอาจารย์พูนศักดิ์คือใคร เค้าเป็น head ของค่ายที่นี่ครับ และก็ตอนนำเสนองานเค้าอยู่ห้องไหนโปรแกรมของห้องนั้นโดนเกรียนหมด คืออย่างเช่นตอนปีผมเข้าค่าย โปรแกรมเค้าทำให้ใส่เลขอาราบิกอาจารย์แกใส่เลขไทยไปเลย แต่ห้องที่มีเค้าอยู่ฮาดี เพราะอาจารย์แกเกรียนดี เรียกความสนใจให้เด็กสนใจได้ดี ปีนี้ไปไม่ได้รับเกีริติบัตรด้วย T_T โดนใช้นั่งเขียนแผ่น CD ให้น้องข้างล่าง + ไปช้าเลยไม่ได้ ปีนี้แย่สุดและ คงเป็นเพราะไปช้าโดนน้องเรียกอาจารย์ด้วย ผมไม่ได้แก่ขนาดนั้นสักหน่อย

ต่อไปเป็นปัญหาในการ Coding

  1. เป็นข้อผิดพลาดจากหนังสือเรื่องการเปิด Form ใหม่ขึ้นมาเพื่อเปลี่ยนหน้า ในหนังสือใช้ Code แบบนี้ครับ
    Form2 f2 = new Form2();  
    //สร้างตัวแปร f2 โดย f2 มีค่าเป็นการสร้าง Form2 ขึ้นมาใหม่(ดูจาก new) 
    public void button1_click(Object sender,EventArgs e){ 
    // บรรทัดนี้อาจจะไม่ถูกเพราะจำไม่ได้ แต่ที่ต้องการคือเมื่อคลิกที่ปุ่ม
        f2.Show(); //แสดง Form2
    }

    แล้ว Code นี้มันมีปัญหายังไงล่ะ น้องๆก็ทำได้ปกตินิ เราลองมาคิดกันว่า ถ้าสมมุติน้องอยากทำปุ่มกลับหน้าแรกจาก Form2 จะเกิดอะไรขึ้น?
    นี่เป็นบางส่วนของ Code ส่วน Form1

    Form2 f2 = new Form2();
    public void button1_click(Object sender,EventArgs e){ 
    // บรรทัดนี้อาจจะไม่ถูกเพราะจำไม่ได้ แต่ที่ต้องการคือเมื่อคลิกที่ปุ่ม
        f2.Show();
    }

    นี่เป็นบางส่วนของ Code ส่วนของ Form2 ที่ต้องการคลิกกลับหน้าแรก

    Form1 f1 = new Form1();
    public void button1_click(Object sender,EventArgs e){ 
    // บรรทัดนี้อาจจะไม่ถูกเพราะจำไม่ได้ แต่ที่ต้องการคือเมื่อคลิกที่ปุ่ม
        f1.Show();
    }

    มองผ่านๆ Code นี่ก็ปกติดีใช่ไหมครับ ใช่ครับตอนแรกผมก็มองว่าปกติดีจนน้องเจอ StackOverFlow ซึ่งไม่น่าเกิดขึ้นเมื่อมันมีแค่ 8 Form ถามว่ามันเกิดได้ยังไง จากการให้ปากคำของน้อง(?) บอกว่ามันเป็นเมื่อใส่ปุ่มกลับหน้าแรก ผมเลยคิดตามว่าทำไม แล้วผมก็เห็นสิ่งนี้ที่ผมไม่เคยทำครับ การประกาศตัวแปร Form2 เป็นแบบ Global และ Inititial ค่าทันที แล้วยังไงล่ะ ลองคิดตามนะครับ ตัวแปร Global แถมกำหนดค่าให้ทันทีหมายความว่ามันทำก่อนหรือเทียบเท่า Constructor (คือทำทันทีเมื่อสร้าง Class ผมไม่ชัวร์ว่าทำตอนไหน แต่คิดว่าทำก่อนด้วยซ้ำ เพราะเราเรียกใช้ใน Constructor ได้) งั้นลองคิดดูครับ เมื่อสร้าง Form1 ขึ้นมา มันจะทำอะไร  มันจะสร้างตัวแปร f2 เพื่อไปที่ Form2 แล้ว Form2 เมื่อถูกสร้างจะทำอะไรก็จะสร้าง f1 เพื่อกลับไปที่ f1 ทันที จากนั้นเมื่อสร้าง Form1 ขึ้นใหม่ มันก็จะสร้าง f2 ของตัวเองขึ้นมากใหม่ให้ลิงค์ไป Form2 ทำซ้ำไปเรื่อยๆ ราวกับ recursive เลยทีเดียว ผลคือ Stack Overflow จ้า

    แล้วเราจะแก้ยังไงล่ะ ตอนแรกผมแก้แบบนี้ครับ พอดีห่างหาย C# ไปนานจำไม่ได้ว่าสมัยก่อนทำยังไง

    Form2 f2;
    //สร้างตัวแปร f2 โดย f2 มีค่าเป็นการสร้าง Form2 ขึ้นมาใหม่(ดูจาก new) 
    public void button1_click(Object sender,EventArgs e){ 
    // บรรทัดนี้อาจจะไม่ถูกเพราะจำไม่ได้ แต่ที่ต้องการคือเมื่อคลิกที่ปุ่ม
        f2 = new Form2();
        f2.Show();
    }

    แต่จำนวนบรรทัดมันเพิ่มขึ้นผมเลยไปลองใหม่ เป็นแบบนี้

    //สร้างตัวแปร f2 โดย f2 มีค่าเป็นการสร้าง Form2 ขึ้นมาใหม่(ดูจาก new) 
    public void button1_click(Object sender,EventArgs e){ 
    // บรรทัดนี้อาจจะไม่ถูกเพราะจำไม่ได้ แต่ที่ต้องการคือเมื่อคลิกที่ปุ่ม
        Form2 f2 = new Form2();
        f2.Show();
    }

    ทั้ง 2 วิธีนี้ได้เหมือนกันเลยนะครับ เพียงเท่านี้ก็ลิงค์ไปลิงค์กลับได้แล้วครับ จนบัดนี้ผมยังไม่รู้เลยว่าไปทำเป็น Global ทำไม?

  2. การเปลี่ยน Form แล้วเมื่อปิด Form2 โปรแกรมไม่ถือว่าถูกปิดด้วย อันนี้ผมมีวิธีแก้สำหรับพวกโปรแกรมที่แสดงแค่ Form เดียวตลอดนะครับ(หมายถึงมีหลาย Form แต่แสดงทีละ Form) ปัญหาเกิดจากอะไร? โดยทั่วไปน้องๆใช้ Code นี้เพื่อทำการซ่อน Form เก่าแล้วแสดง Form ใหม่
    //สร้างตัวแปร f2 โดย f2 มีค่าเป็นการสร้าง Form2 ขึ้นมาใหม่(ดูจาก new) 
    public void button1_click(Object sender,EventArgs e){ 
    // บรรทัดนี้อาจจะไม่ถูกเพราะจำไม่ได้ แต่ที่ต้องการคือเมื่อคลิกที่ปุ่ม
        Form2 f2 = new Form2();
        f2.Show();
        this.Hide(); //ซ่อน Form ปัจจุบัน
    }

    ทำให้เมื่อปิด Form อื่นๆ แต่จริงๆมันก็จะยังถือว่า Form นั้นๆเปิดอยู่ ดังนั้นโปรแกรมจึงไม่ปิดสักทีครับ แล้วเราจะแก้ยังไงล่ะ อันนี้เป็นวิธีที่ผมไปแนะนำน้องๆครับ คือสร้าง Event ที่ชื่อ FormClosed ของ Form จะมี Code ประมาณนี้(พิมพ์เองไม่ได้นะครับ)

    public void Form2_FormClosed(object sender,EventArgs e){
    //บรรทัดบนนี้โปรแกรมสร้างให้ผมจำไม่ได้ว่าพิมพ์ยังไงเหมือนกัน
        Application.Exit();
        //คือบอกว่าเมื่อมีการปิด Form นี้ให้ออกจากโปรแกรม 
        //แน่นอนว่า .Hide() แค่ซ่อนไม่ได้ปิดนะครับ
    }
  3. ต่อไปอันนี้เป็นส่วนที่ยากที่สุดเลยก็ว่าได้เป็นการส่งค่าข้าม Form ซึ่งในหนังสือแนะนำให้ใช้ Delegate ครับ ซึ่งผมยังไม่เคยใช้มันเลย ผมเลยมีวิธีเกรียนๆนำเสนอ 2 วิธีคือ 1 สร้าง Constructor ไว้รับส่งค่า แต่สำหรับน้องอาจจะเข้าใจยากไปนิด ผมแนะนำอีกวิธี เป็นวิธีเกรียนสะท้านโลกเลยทีเดียว คือประกาศตัวแปรให้รู้จักทั้งโปรแกรม แล้วทำยังไงล่ะ สมมุติผมต้องการให้ตัวแปร score เป็น int และทั้งโปรแกรมรู้จัก ผมก็แค่ไปเปิด Program.cs แล้วเพิ่มบรรทัดนี้ไปล่าง Function ที่ชื่อ Main
    public static int score = 0;

    เป็นประมาณนี้ครับ

    private static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
    
    public static int score = 0;

    เพียงเท่านี้ทุก Form ก็รู้จักตัวแปรนี้แล้วครับ แต่เวลาเรียก ต้องเรียกแบบมีพิเศษหน่อยครับ คือต้องเรียกแปบนี้

    Program.score += 1; 
    //ประมาณนี้คือบอกให้ตัวแปร score + เพิ่มค่าไปอีก 1 เรียกที่ Form ไหนก็ได้ครับ

    จริงๆ ผมว่าถ้าประกาศแบบนี้ทำที่ Form1 หรือที่อื่นๆก็ได้แต่เวลาเรียกจะเป็น ชื่อClass.ชื่อตัวแปร เช่น

    Form1.score+=1;

    แต่แบบนี้ผมยังไม่ได้ทดสอบคิดว่าได้นะครับ

    นอกจากนั้นยังมีอีกแบบที่ทำได้ แต่ Code อาจจะยาวสักหน่อยนะครับ ไม่ Proof แนวคิดด้วย กลัว Proof แล้วแปก ยังไม่ได้ลองเหมือนกัน 55

    void Button1Click(object sender, EventArgs e)
    {
        this.Hide();
        //สั่งซ่อน Form ปัจจุบัน
        Form2 f2 = new Form2();
        f2.ShowDialog();
        //ShowDialog นั้นคือจะต้องมีการปิด Form ก่อนหน้าก่อน จึงจะทำบรรทัดต่อไป
        this.Close();
        // ปิด Form แม่ม
    }

ปัญหาอื่นๆที่เจอคือ ควรจะสอนหรือหา Solution สำหรับการทำงานร่วมกันที่ดีกว่านี้ เพราะจากที่สังเกต การทำงานจะทำได้แค่ทีละคนทำให้ช้า การแยก Project แล้วค่อยๆเอามารวม Form ก็เป็นไปได้ยาก + คงไม่ได้สอน ทำให้การทำ Project เป็นไปได้อย่างลำบาก Solution ที่คิดไว้แต่ไม่ได้ Proof คือ Share Folder ของแต่ละคนไปทำที่เดียวกัน โดยมีข้อแม้ว่าห้ามเปิด Form เดียวกัน ไม่งั้นอาจจะเกิดข้อมูลสูญหายได้

บันทึกอื่นๆ ไปค่ายปีนี้ก็ดีกลับมาเหมือนปกติ คือจัดตอนนักเรียนของเค้าติดธรรมศึกษา(ขอบอกว่าโรงเรียนหญิงล้วน แต่ไม่ได้ไปส่องหรอก) กับ เอมน่ารักดีนะ

FengOffice โปรแกรม Project Management แบบ Web Based ที่ดีที่สุด(มั้ง)

[OUTDATED ไม่ต้องอ่านครับ เสียเวลา ผมเขียนในสมัยไม่รู้ความเท่าไหร่]

วันนี้ผมมาแนะนำโปรแกรม FengOffice ที่ดีที่สุดสำหรับผม ถามว่าผมเอาเกณฑ์อะไรมาวัด ผมสามารถใช้เป็นได้ใน 5 นาทีไงครับ ผมลองมาหลายตัว ตัวนี้เปนตัวเดียวที่ผมคลำง่ายสุดใน 5 นาทีหรืออาจจะเพราะผมคลำตัวอื่นๆมาก่อนก็เป็นได้ ทำให้ผมสารถใช้เป็นอย่างรวดเร็ว โดยตัวโปรแกรมนี้เป็น Web Base คือต้องทำงานผ่านเว็บกล่าวคือหากคุณจะใช้ fengoffice คุณจำเป็นต้องมี Web Server, MySQL เป็นอย่างน้อย และที่สำคัญที่สุดขาดไม่ได้คือพวก Web Browser พวก Chrome หรือ Firefox ข้อดีของการเป็น Web base ก็คือคุณสามารถหา server มาตั้งแล้วเข้าถึงข้อมูลจากที่ไหนก็ได้

เมื่อลงเสร็จแล้วครั้งแรกที่เข้ามันจะให้คุณตั้ง username password ของ admin นะครับ ถ้าหากผ่านหน้านั้นมาก็สามารถ login ได้แล้วครับ

เมื่อ login ได้จะเจอหน้าจอติดต่อผู้ใช้ง่าย
ภาพ Interface ของ FengOfficeจะเห็นว่าจะแบ่งเป็น block มุมบนตรงส่วนของ Workspace จะเป็นส่วนของ Project งานที่เรามี ซึ่งเพิ่มได้โดยใช้ปุ่ม Add ข้างๆช่อง search ด้านล่าง Workspace มีส่วน People คือผู้ใช้ต่างๆ แต่พอดีผมใช้คนเดียวเลยไม่ได้ทดสอบส่วนนี้ ด้านขวาจะมีรายละเอียดคร่าวๆของ Project ของเรา จริงๆแล้วผมใช่แค่ Task ดังนั้นตัวอื่นผมไม่สามารถทราบได้ 55

ภาพ Interface ของ FengOffice ในหน้า Task

จากภาพจะเห็นว่าหน้า task จะมีรายละเอียดต่างๆของงานใน Project นั้นอยู่ โดยเราสามารถเพิ่มงานใน Project ได้ 2 แบบ

  • MileStone ผมแนะนำให้อันนี้เป็นงานใหญ่ๆที่มีงานย่อยๆอยู่ด้านใน
  • Task อันนี้ผมแนะนำให้ควรเป็นงานย่อยๆที่อยู่ใน MileStone หาก Task อยู่ใน MileStone เมื่อกด Complete เพื่อจบ Task (เอาเมาส์เลื่อนไปหรือคลิกที่ task จะมีปุ่มขึ้นมา) แถบแสดงสถานะของ MileStone จะขยับอัตโนมัติ แต่ถ้าเป็น Subtask หรือ task จะต้องกดเข้าไปใน task เพื่อ edit percent เอง แต่ถ้าหากตั้ง Estimated Time ไว้มันจะนับ Percent ตามเวลาที่เราทำ task นั้นให้

จะ เห็นได้ว่าผมมี MileStone 1 อัน และมี task ย่อยในนั้น 2 อัน อันนึงผมสั่งให้ตัวผมทำ อีกอันสั่งให้คนอื่นทำ(Company ที่มันบังคับให้สร้างตอนแรก)  โดย task ที่เสร็จแล้วจะมีขีดค่าขึ้น

ก็จบ review คร่าวๆประมาณนี้ ลองๆไปมั่วกันเองดูนะครับ น่าใช้มาก

XAMPP เข้า phpMyAdmin ไม่ได้ ติด Error 403 Access forbidden!

อันนี้ผมไม่รู้ว่าเป็นเฉพาะ Ubuntu รึเปล่านะครับ แต่ถ้าหากใครประสบปัญหาเข้า phpMyAdmin ของ XAMPP แล้วเจอหน้า Error 403 Access forbidden! เรามีวิธีแก้ดังนี้ครับ

ตกลงกันก่อน

ถ้าผมพูดถึงโฟลเดอร์ config จะหมายถึง

  • ใน linux จะหมายถึง /opt/lampp/etc/
  • ใน windows จะหมายถึง xampp/apache/conf

ตามแบบฉบับทั่วๆไปที่หาเจอ

  1. ให้ใช้โปรแกรม text editor เช่น notepad,notepad++,geany เปิดไฟล์ extra/httpd-xampp.conf ที่อยู่ในโฟลเดอร์ config
    ประมาณว่า /opt/lampp/etc/extra/httpd-xampp.conf
    หรือ C:\XAMPP\apache\conf\extra\httpd-xampp.conf
  2. เลื่อนไปล่างสุดเราจะเจอ
    <LocationMatch "^/(?i:(?:xampp|security|licenses|phpmyadmin|webalizer|server-status|server-info))">
    	Order deny,allow
    	Deny from all
    	Allow from ::1 127.0.0.0/8 \
    		fc00::/7 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
    		fe80::/10 169.254.0.0/16
    
    	ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
    </LocationMatch>

    ให้เราแก้เป็น

    #<LocationMatch "^/(?i:(?:xampp|security|licenses|phpmyadmin|webalizer|server-status|server-info))">
    #	Order deny,allow
    #	Deny from all
    #	Allow from ::1 127.0.0.0/8 \
    #		fc00::/7 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
    #		fe80::/10 169.254.0.0/16
    #
    #	ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
    #</LocationMatch>

    (ใส่ # ไปข้างหน้าของทุกบรรทัด)

  3. Save แล้ว restart apache ใหม่ แล้วลองเข้าดู

อธิบายเพิ่มเติมที่แก้ httpd-xampp.conf

ส่วนที่ให้แก้คือส่วน ที่บอกว่าหากเข้า folder ที่ชื่อว่า xampp|security|licenses|phpmyadmin|webalizer|server-status|server-info ( | หมายถึงหรือ) ให้ทำการปิดกั้นการเข้าถึงทั้งหมด อนุญาติเฉพาะ IP ที่เป็นเครื่องตัวเอง (127.0.0.1,::1) หรือเครื่องที่เป็นภายในเครือข่ายเดียวกันเท่านั้น (โดยทั่วไปคือน้ำหน้าด้วย 10.0.*,172.16.*,169.254.* และ 192.168.*)

แล้วถ้าไม่ได้ผล ผมแนะนำวิธีนี้แทนครับ

  1. ให้ใช้โปรแกรม text editor เช่น notepad,notepad++,geany เปิดไฟล์ extra/httpd-xampp.conf ที่อยู่ในโฟลเดอร์ config
  2. ให้แก้ส่วนล่างสุดจากวิธีด้านบนกลับให้เป็นเหมือนเดิม(คือเอา # หน้าบรรทัดออก)
  3. ก่อนบรรทัด
    </LocationMatch>

    ให้เพิ่มบรรนี้ลงไปครับ

    Require all granted

    จะได้เป็นแบบนี้ครับ

    <LocationMatch "^/(?i:(?:xampp|security|licenses|phpmyadmin|webalizer|server-status|server-info))">
            Order deny,allow
            Deny from all
            Allow from ::1 127.0.0.0/8 \
                    fc00::/7 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
                    fe80::/10 169.254.0.0/16
    
            ErrorDocument 403 /error/XAMPP_FORBIDDEN.html.var
            Require all granted
    </LocationMatch>
  4. Save Restart Apache แล้วลองเข้าใหม่ดูครับ