#Best Practices

ผ่าน sandbox ไม่ได้แปลว่าใช้ได้จริง — สัญญาณหลอก 7 แบบ
ระบบสั่งซื้ออัตโนมัติที่ผมเขียนผ่าน sandbox ของผู้ให้บริการครบทุกคำสั่ง แต่เกือบทุกอย่างที่ sandbox บอกเป็นคนละเรื่องกับของจริง ทั้งเวลาตอบกลับ ยอดที่ถูกตัด ชื่อที่ใช้ได้ และรายการที่สร้างสำเร็จแต่ค้นไม่เจอ รวมสัญญาณหลอก 7 แบบพร้อมวิธีเขียนโค้ดให้ไม่หลงเชื่อ

ให้ AI คนละค่ายมาตรวจโค้ดที่ AI เขียน — กระบวนการ ไม่ใช่ความศรัทธา
พอร์ตเครื่องคำนวณจากสเปรดชีตวิศวกรรม 35 ชีตด้วย AI แล้วจะรู้ได้ยังไงว่าถูก บทความนี้เล่ากระบวนการให้เอเจนต์อีกค่ายมาตรวจอิสระสามรอบ กติกาที่ต้องตั้งก่อนเริ่ม ชั้นความเชื่อมั่นที่กันการโม้เกินหลักฐาน และคลาสความผิดพลาดที่ AI พลาดซ้ำ ๆ ทุกรอบ

ส่งไฟล์ขึ้นโฮสต์แล้วทับกันเงียบๆ สามกับดักตอนคัดลอกไฟล์
ส่งไฟล์สองตัวที่ชื่อซ้ำกันขึ้นโฮสต์พร้อมกัน ตัวหลังทับตัวแรกเงียบๆ ไม่มี error ไม่มี exit code ผิด เว็บยังตอบ 200 ทุกหน้า แค่หน้าภาษาอังกฤษกลายเป็นหน้าภาษาไทย นี่คือสามกับดักที่ทำให้การคัดลอกไฟล์เสียหายโดยไม่มีอะไรเตือน

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

Build APM บน Windows ตอนที่ 5: คอมไพล์ ImageMagick 7 ให้ PHP imagick
ตอนที่ 5 ของซีรีส์ Build APM บน Windows พาคอมไพล์ ImageMagick 7.1.2-34 กับ delegate library ราว 40 ตัวจาก source ด้วย toolchain ทางการ พร้อมแพตช์ channel mask 64 เป็น 32 ที่ทำให้ imagick build ผ่าน และเหตุผลที่ HEIC เขียนไม่ได้

Build APM บน Windows ตอนที่ 4: คอมไพล์ MariaDB 11.8 LTS เอง
ตอนที่ 4 ของซีรีส์ Build APM บน Windows พาคอมไพล์ MariaDB 11.8.9 จาก source ด้วย CMake และ Ninja ทีละขั้น ตั้งแต่เตรียมเครื่องมือ รันสคริปต์ ทดสอบบนพอร์ต 3399 ไปจนถึงเหตุผลที่ต้องล็อก collation เป็น utf8mb4_unicode_ci

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

ตารางเกณฑ์ในสเปรดชีตที่ไม่ได้ผูกสูตร ถอดค่าคงที่กลับเป็นสูตร
ชีตที่มีตารางเกณฑ์วางอยู่ข้าง ๆ แต่ไม่ได้ผูก VLOOKUP คนอ่านตารางแล้วพิมพ์ค่าลงช่องเอง พลาดเมื่อไรไม่มีใครรู้ บทความนี้ว่าด้วยการแยกช่องสูตรกับช่องพิมพ์มือออกจากกัน แล้วถอดคอลัมน์ตัวคูณ 16 ค่ากลับมาเป็นสูตรเดียวที่ตรงทั้งตาราง

เว็บสองภาษา 26 หน้า ทำไมต้องกลายเป็น .php แล้วลิงก์พังทั้งเว็บ
หน้าโปรดักชันโชว์แท็ก PHP เป็นตัวหนังสือดิบ เพราะเว็บเซิร์ฟเวอร์เสิร์ฟ .html เป็นไฟล์ static พอเปลี่ยนทั้ง 26 หน้าเป็น .php ลิงก์ก็พังทั้งเว็บ แล้วพอทำ clean URL ต่อหน้าย่อยก็เด้งกลับเป็น .php เพราะ rewrite กับ 301 ทำครึ่งเดียว บทความนี้คือ .htaccess เต็ม กติกา $base แปดกรณี และสคริปต์ที่ทำทีเดียวทั้งเว็บ

ยิง API สองหมื่นกว่าครั้ง ให้หยุดกลางทางแล้วต่อได้ และไม่ได้ไฟล์เสีย
งานยิง API สร้างไฟล์ 26,850 ไฟล์บนโควตาที่จำกัด 20 ครั้งต่อนาที สามชิ้นที่ขาดไม่ได้คือ ตัวหน่วงที่นับรวมกันทั้งระบบ การต่องานจากของที่มีอยู่บนดิสก์ และตัวตรวจไฟล์แยกต่างหาก เพราะไฟล์ที่หลุดตอนเน็ตสะดุดมีนามสกุลถูกและขนาดไม่เป็นศูนย์

แบนเนอร์คุกกี้ที่กั้นได้จริง โหลด GTM กับ GA4 หลังกดยอมรับเท่านั้น
แบนเนอร์คุกกี้ส่วนใหญ่ขึ้นมาสวยแต่ไม่ได้กั้นอะไร เพราะ GTM กับ GA4 ถูกโหลดไปตั้งแต่บรรทัดแรกของหน้าแล้ว บทความนี้คือโครงที่โหลด container เมื่อกดยอมรับเท่านั้น วาง GA4 เป็นแท็กข้างใน GTM กันนับซ้ำ ซ่อนช่อง AdSense ไว้ก่อน และตัวตรวจที่นับ request ปลายทางให้เป็นศูนย์

หน้าเว็บว่างเปล่า ไม่มี error สักบรรทัด เพราะตั้งชื่อฟังก์ชันว่า top
deploy ขึ้นไปแล้วหน้าว่าง ไม่มี error ในล็อก ไม่มีอะไรผิดใน node --check แต่เบราว์เซอร์ฆ่าทั้งสคริปต์ตั้งแต่บรรทัดแรกเพราะมีฟังก์ชันชื่อ top ไปชนกับ window.top พร้อมรายชื่อที่ต้องเลี่ยง กับดักลำดับการโหลดสคริปต์ และด่านตรวจด้วย Playwright ที่ควรมีทุกโปรเจกต์

เขียนค่าลง DirectAdmin ตอนที่ API มีแต่ฝั่งอ่าน ต้องขับฟอร์มของแผงเอง
บันทึกการทำให้แอปหลังบ้านสร้างและแก้แพ็กเกจโฮสติ้งบน DirectAdmin ได้ ทั้งที่ CMD_API ตัวทางการมีแต่คำสั่งอ่าน ต้อง POST เข้าฟอร์มของแผงควบคุมเอง พร้อมกฎการยืนยันผลที่ห้ามใช้ regex และสวิตช์ตัดวงจรสองชั้นที่ปิดไว้เป็นค่าตั้งต้น

nameserver ที่ registrar ไม่ตรงกับระบบบิลลิ่ง ออดิตสามฝั่งก่อนแก้
บันทึกการไล่บั๊ก "Wrong response from the server" ตอนกดเปลี่ยน nameserver ในระบบบิลลิ่ง ที่พังเฉพาะโดเมนที่มีข้อมูล glue IP ตกค้าง แล้วทำออดิตเทียบสามฝั่งระหว่าง registrar ระบบบิลลิ่ง และโซน DNS จริง ก่อนจะกล้าแก้อะไรสักตัว

ให้ AI อ่านเอกสาร แต่ให้โค้ดเป็นคนคิดเลข
controller บังคับให้คนกรอกอยู่ในช่วง 0 ถึง 100 แต่เส้นทางที่ AI อ่านค่าจากเอกสารแล้วป้อนเข้ามาตรวจแค่ว่าเป็นตัวเลข ค่าติดลบตัวเดียวดันผลลัพธ์ขึ้นไป 5.25 เท่าโดยไม่มี error — บทเรียนเรื่องการมองเอาต์พุตของ AI เป็น input ที่ไม่น่าเชื่อถือเท่ากับที่คนกรอก

แอปเป็น UTC คนคิดเป็นเวลาไทย — เพี้ยน 7 ชั่วโมงแบบไม่มี error
ตั้งเวลาเผยแพร่ไว้บ่ายสาม ของขึ้นจริงสี่ทุ่ม ไม่มี error ไม่มี log อะไรผิด เพราะแอปเก็บเป็น UTC แต่คนกรอกคิดเป็นเวลาไทย บทความนี้ไล่ตั้งแต่ค่าที่ตั้งใน env แล้วไม่มีผล ไปจนถึงบรรทัดเดียวที่เขียนหน้าปัดไทยลงคอลัมน์ที่ทุกคนอ่านเป็น UTC

ไฟล์ลับคุม 600 ครบ แต่ log 0644 ถูกอัปออกนอกเครื่องทุกคืน
เข้ารหัส .env เรียบร้อย คุมสิทธิ์ไฟล์ลับครบทุกตัว แต่ข้อมูลลูกค้ายังรั่วออกนอกเครื่องทุกคืนผ่านทางที่ไม่มีใครจัดว่าเป็นความลับ นั่นคือไฟล์ log ที่อ่านได้ทั้งเครื่องและถูกมัดรวมขึ้น object storage พร้อม backup พร้อมวิธีปิดที่ต้นทางด้วยการ log แค่รหัสผลลัพธ์

เว็บกับคิวคนละผู้ใช้ — mkdir 0700 ฆ่า default ACL ทิ้งทั้งโฟลเดอร์
แอปตัวเดียวแต่รันด้วยสองผู้ใช้ ฝั่งเว็บเป็น php-fpm ฝั่งคิวเป็นอีกบัญชีหนึ่ง ตั้ง default ACL ไว้ครบแล้วยังเขียนข้ามกันไม่ได้ ต้นเหตุคือ mkdir โหมด 0700 ที่ไปตั้ง mask ทับจนสิทธิ์ ACL หายเกลี้ยง พร้อมกับดักเรื่องลบไฟล์ที่ต้องมีสิทธิ์ที่โฟลเดอร์ ไม่ใช่ที่ไฟล์

php -l ผ่าน แต่หน้าเว็บ 500 — ประตูตรวจก่อน commit ที่คอมไพล์จริง
เทมเพลตพังสองรอบในเดือนเดียวทั้งที่ php -l ผ่านหมด เพราะ php -l ไม่รู้จักไวยากรณ์ของ Blade บทความนี้คือประตูตรวจ 6 ด่านที่ผมวางไว้ก่อน commit — คอมไพล์ view จริงแล้ว lint ไฟล์ที่คอมไพล์ออกมาซ้ำอีกชั้น พร้อมสคริปต์กวาด GET ทุก route ผ่าน Kernel

งานที่ยิงออกนอกระบบ ต้องจองสถานะก่อนยิงเสมอ
guard แบบ "อ่านสถานะแล้วค่อยยิง" ดูปลอดภัยจนถึงวันที่ worker โดนฆ่าหลังยิงแต่ก่อนเขียนฐานข้อมูล แล้ว retry ก็ยิงซ้ำให้ลูกค้าเห็นของสองรอบ บทความนี้คือชุดกันซ้ำทั้งชุดที่ผมใช้ ตั้งแต่การจองแบบ atomic ไปจนถึง retry_after กับ failed() ที่ห้ามทับสถานะที่สำเร็จแล้ว

แจ้งเตือนถี่เกินเท่ากับไม่ได้แจ้ง จูนบอทให้คนอ่านจริง
วันเดียว 28 เหตุการณ์กลายเป็น 56 ข้อความ และ 57 เปอร์เซ็นต์ของทั้งหมดเป็นการเตือนซ้ำทุก 30 นาที บทความนี้ว่าด้วยการแยกชั้นผู้รับ การรวมรอบที่ซ้อนกัน สถานะที่รอดจากการรีสตาร์ต และเหตุผลที่ห้ามใส่ keepalive กับ session ของแอปแชต

ชุดแบบผังโรงงานอาหาร ต้องมีกี่แผ่น สเกลเท่าไร ลงกระดาษยังไง
ชุดแบบประกอบคำขอโรงงานอาหารมี 7 รายการ แต่ละแผ่นมีช่วงสเกลของตัวเอง และมีเลขที่ต้องคำนวณก่อนวาดคือ ผังกว้างกี่เมตรลง A4 หรือ A3 ที่ 1 ต่อ 100 ได้ไหม ถ้าไม่ได้จะแบ่งแผ่นยังไงไม่ให้สเกลเพี้ยน

จากโมเดลเป็นผังตัดเหล็ก 6 เมตร แล้วออกชีทตัดให้ช่าง
อ่านความยาวชิ้นส่วนจากโมเดล รวมรายการซ้ำ แล้วจัดผังตัดแบบ first-fit decreasing บนเส้นมาตรฐาน 6 เมตร เผื่อร่องใบเลื่อย 3 มิลลิเมตร พร้อมทางเลือกบากคอหักฉากที่ลดรอยต่อจาก 12 เหลือ 6

ถอดปริมาณงานจากโมเดล SketchUp ด้วยสคริปต์ Ruby
โมเดลที่ปั้นไว้แล้วมีตัวเลขทุกตัวที่ใบถอดปริมาณต้องการ ขอแค่ตั้งชื่อกลุ่มให้อ่านได้ตั้งแต่แรก แล้วเขียนสคริปต์ไล่ grep พร้อมกับดักสองข้อที่ทำให้พื้นที่เพี้ยนเท่าตัว

เลือกขนาดสายเมนกับเบรกเกอร์ พิกัดกระแสขึ้นกับวิธีติดตั้ง
บันทึกการเลือกสายเมนกับเบรกเกอร์ของฟีดเดอร์ใหม่ 253 A ทำไมสาย CV ขนาดเดียวกันรับได้ 227 A หรือ 364 A ขึ้นกับวิธีเดิน และทางเลือกลดขนาดสายลงเป็น 95 แล้วชดเชยด้วยกติกาการเปิดเครื่อง แลกกับการที่เมนจะทริปถ้าใครเปิดผิดกติกา

ส่งไฟล์จากงานอัตโนมัติเข้า Telegram กับเพดาน 50 MB ของ Bot API
วางบริการเล็ก ๆ ในเครื่องที่รับไฟล์จากสคริปต์แล้วส่งเข้า Telegram ให้ตัวเอง เป็นช่องทางออกทางเดียวล้วน ไม่มี polling ไม่รับคำสั่งกลับ พร้อมเพดานจริงของ Bot API ที่ต้องรู้ก่อนเขียน ทั้ง 50 MB ต่อไฟล์ รูปเกิน 10 MB ที่ต้องส่งเป็นเอกสาร และกับดักภาษาไทยใน curl บน Windows

พอร์ต CDP ยังตอบ แต่สั่งงานไม่ได้ เพราะ Chrome อัปเดตทับตัวเอง
เครื่องเดียวรันงานอัตโนมัติหลายตัวที่ต้องใช้เบราว์เซอร์จริง แล้วเจอสองเรื่องพร้อมกัน — งานแย่งแท็บกันเองจนได้ผลของคนอื่น และ Chrome อัปเดตไฟล์ทับตัวเองขณะโปรเซสยังรัน ทำให้พอร์ตยังตอบแต่สั่ง Runtime.evaluate ไม่ได้ บทความนี้คือวิธีแยกงาน วิธีตรวจให้เจอ และตัวซ่อมที่ทำงานเอง

ไฟดับ 25 ชั่วโมง แล้วงานตามเวลาที่พลาดไปหายไปเลย
เครื่องที่รันงานอัตโนมัติดับสามรอบในสามวัน รอบยาวสุด 25 ชั่วโมง พอกลับมาถึงรู้ว่างานที่ตั้งด้วย Task Scheduler ตรง ๆ หายไปทั้งรอบไม่รันชดเชย ส่วนงานที่ผ่านตัวสั่งงานซึ่งเทียบเวลาเองไล่ตามครบทุกตัว บทความนี้คือค่าที่ต้องเปิด สิ่งที่ห้ามทำตอนกู้ และกับดักที่ทำให้อ่านสถานะผิด

งานอัตโนมัติหยุดส่งรูป 4 วัน เพราะ subprocess เลือก ssh ตาม PATH
เขียน subprocess.run(["ssh", ...]) แล้วปล่อยให้ระบบเลือกไบนารีตาม PATH ของคนเรียก วันหนึ่งคนเรียกเปลี่ยน ไบนารีเปลี่ยนตาม งานส่งไฟล์ตายเงียบ 4 วันโดยรายงานว่าสำเร็จทุกครั้ง บทความนี้คือวิธีจับอาการ และตัวช่วยที่ probe ไบนารีจริงก่อนใช้ พร้อมด่านตรวจความครบก่อนบอกว่าเสร็จ

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

audit ระบบ prod ที่มีข้อมูลลูกค้าจริง โดยไม่ทิ้งขยะสักแถว
เจ้าของระบบสั่งให้ทดสอบทั้งระบบบนเครื่องจริงที่มีข้อมูลลูกค้าอยู่ แล้วห้ามเหลือแถวขยะไว้แม้แถวเดียว วิธีที่ผมใช้คือ bootstrap Laravel เองแล้วเรียก controller ตรง ๆ ใน transaction ที่ rollback ทิ้ง พร้อมนับ COUNT ทุกตารางก่อนและหลังเป็นหลักฐาน

crontab ของ user เว็บ ไม่ใช่ crontab ที่ cron รันจริง
แก้ตารางเวลาผ่านหน้าเว็บแล้วงานยังยิงตามเวลาเก่า เพราะสคริปต์เขียน crontab ของ user ที่เว็บรันอยู่ ไม่ใช่ของ user ที่ cron อ่านจริง วิธีตรวจให้เจอใน 3 คำสั่ง sudoers drop-in ที่ใช้ และวิธีออกแบบไม่ให้มันหลุดอีก

เก็บ secret ใน .env แบบเข้ารหัส แล้วถอดอัตโนมัติตอน config โหลด
วิธีเก็บรหัสผ่านและ API key ใน .env ของ Laravel เป็น ciphertext แล้วให้ config ถอดกลับเองตอนโหลด ด้วย helper ตัวเดียวที่ตรวจเองว่าค่าไหนเข้ารหัสไว้ พร้อมกับดัก APP_KEY ต่าง environment ที่ทำให้ระบบล่มทั้งชุดถ้าพลาด

ตรวจ security เว็บ Laravel ที่ deploy แล้ว — ไล่ 3 ชั้นตามลำดับที่ควรแก้
หลัง deploy Laravel ขึ้น production ควรไล่ตรวจความปลอดภัย 3 ชั้น — external probe หา endpoint ที่รั่ว, ตรวจไฟล์/สิทธิ์บนเซิร์ฟเวอร์, แล้ว grep หาช่องในโค้ด บทความนี้ให้ชุดคำสั่งพร้อมลำดับความสำคัญ P0-P2 ที่ควรแก้ก่อนหลัง

เขียนสคริปต์บน Windows ไปรันบน Linux — สองกับดักที่ทำไฟล์ค้างเซิร์ฟเวอร์
เขียน helper script บน Windows แล้ว scp ขึ้นไปรันบน Linux เป็นงานประจำ แต่มีสองอย่างที่กัดซ้ำ ๆ — path แบบ d:\ ที่ฝังในสคริปต์กลายเป็นชื่อไฟล์ประหลาดใน /tmp จนโดน file monitor จับ และไฟล์ token/payload ที่ลืมลบทิ้งไว้บนเซิร์ฟเวอร์ บทความนี้สรุปกฎกันพลาด

audit ความปลอดภัยเซิร์ฟเวอร์ Debian shared-host แบบ read-only — เริ่มยังไงไม่ให้แบนตัวเอง
ตรวจความปลอดภัยเซิร์ฟเวอร์ Debian ที่รัน DirectAdmin แบบ read-only ก่อน — แต่กับดักแรกคือทราฟฟิกจากการ scan เองเข้าเงื่อนไข brute-force ของ CSF จนแบน IP ตัวเอง บทความนี้วางลำดับ audit ที่ปลอดภัย + จุดที่ต้องดูในยุค 2024-2026

ลูกค้าเช็คเมลแล้วโดน firewall แบนยกออฟฟิศ — แก้ด้วย auto-whitelist จาก login
พฤติกรรมลูกค้าเมลจริงหน้าตาเหมือน bot เป๊ะ — เครื่องในออฟฟิศยิงรหัสเก่ารัวๆ จนโดน CSF แบนทั้งวง บทความนี้เล่าระบบ auto-whitelist ที่เกาะเหตุการณ์ login สำเร็จ + GeoIP ไทย แล้ว temp allow 24 ชั่วโมง พร้อมกับดัก 5 ข้อที่เจ็บมาแล้ว

คุม Linux server ด้วย AI ผ่าน SSH ให้ปลอดภัย ไม่เผลอพังระบบ
วิธีที่ผมใช้จริงในการเอา Claude มาช่วย audit และแก้ security ของ Linux server ผ่าน SSH ตั้งแต่เตรียมเครื่อง เก็บความลับ ไปจนกฎเหล็กก่อนแตะ production

วางระบบ Backup DirectAdmin ใหม่ด้วย NFS และ POSIX ACL จากงานจริง
บันทึกการรื้อระบบ backup ของ DirectAdmin server หลัง migrate เครื่องใหม่ — จาก FTP push ที่พังสามชั้น มาเป็น NFSv4 hard mount + POSIX ACL พร้อมบทเรียนระดับ kernel ที่กว่าจะลงตัว.