Debug CI4 ยังไงให้ได้ผล?
เมื่อ Log เพียงอย่างเดียวไม่พอ — แนะนำ DEX
เคยเจอ error แปลกๆ ใน production แล้วเปิด log ขึ้นมาดู แต่รู้สึกว่า "มันบอกแค่นี้เองเหรอ?" ไม่รู้ว่า request ทำอะไรไปก่อนจะ fail ไม่รู้ว่า query ไหนรันไปบ้าง ไม่รู้ว่า bug นี้เคยเกิดแล้วหรือเปล่า — บทความนี้มีคำตอบให้ครับ
🔍 ปัญหาที่นักพัฒนา CI4 ทุกคนเจอ
ถ้าคุณเคยทำงานกับ CodeIgniter 4 (CI4) มาสักพัก คุณคงรู้ดีว่า การ debug แอปพลิเคชันจริงๆ นั้น ไม่ง่ายอย่างที่คิด โดยเฉพาะเมื่อ application ขึ้น production ไปแล้ว
สิ่งที่เรามักเห็นใน log file มักมีหน้าตาแบบนี้:
// log ที่เห็นใน application/logs/
ERROR - 2025-06-09 14:32:11 --> Call to a member function getResult() on bool
ERROR - 2025-06-09 15:01:44 --> Trying to access array offset on value of type nullLog บอกได้ว่า error เกิด ที่ไหน แต่มันไม่บอกว่า:
- Controller method ไหนที่รับ request นั้น?
- Database query อะไรรันไปก่อนหน้า?
- Error เกิดใน service, model, หรือ API call?
- Bug นี้เคยถูก fix แล้วและ กลับมาใหม่ หรือเปล่า?
ข้อสุดท้ายนี่เจ็บปวดที่สุดครับ บางครั้งเรา fix bug ไปแล้ว แต่สัปดาห์ต่อมามันกลับมา แล้วเราก็เริ่ม debug ใหม่ราวกับว่ามันเป็น bug ใหม่ — ทั้งที่จริงๆ มันคือ regression
🛠️ DEX คืออะไร?
DEX คือ open-source issue tracking tool ที่สร้างขึ้นมาเพื่อ CodeIgniter 4 โดยเฉพาะ มันไม่ได้แค่ดักจับ error แต่มันบันทึก context รอบๆ request ทั้งหมดให้คุณด้วย เพื่อให้คุณเข้าใจได้ว่า:
แอปทำอะไรก่อนที่มันจะพัง
issue นี้เป็น ใหม่, ignored, resolved หรือ regressed?
request lifecycle เป็นยังไงแบบ timeline
มี slow query หรือ failed query ก่อน error ไหม?
ลูกค้าแจ้งว่า checkout ล้มเหลว — Log บอกว่ามี exception แต่คำถามคือ: cart โหลดสำเร็จไหม? payment provider ถูกเรียกไหม? error เกิดก่อนหรือหลัง payment? DEX ตอบคำถามพวกนี้ได้ทั้งหมด
⚙️ ติดตั้ง DEX ใน CI4 Project
การติดตั้ง DEX ทำได้ผ่าน Composer เหมือน package ทั่วไปครับ:
# ติดตั้งผ่าน Composer
composer require sarutobi/dexจากนั้น run migration เพื่อสร้าง table ในฐานข้อมูล:
# Run migration
php spark migrate --allแล้วก็เพิ่ม DEX filter เข้าไปใน app/Config/Filters.php:
use Sarutobi\Dex\Filters\DexFilter;
// ใน $globals หรือ $filters ตาม route ที่ต้องการ track
public $globals = [
'before' => [
DexFilter::class,
],
];เพียงเท่านี้ DEX ก็จะเริ่มจับ request ทุกอันของคุณแล้ว
📊 เปรียบเทียบ: Log อย่างเดียว VS ใช้ DEX
| สิ่งที่ต้องการรู้ | Log ไฟล์อย่างเดียว | ใช้ DEX |
|---|---|---|
| Error message พร้อม stack trace | ✓ มี | ✓ มี |
| Controller / Method ที่รับ request | ✗ ไม่มี | ✓ มี |
| Database queries ที่รันก่อน error | ✗ ไม่มี | ✓ มี |
| Request lifecycle timeline | ✗ ไม่มี | ✓ มี |
| สถานะ issue (new / resolved / regressed) | ✗ ไม่มี | ✓ มี |
| ค้นหาและจัดการ issue แบบมี workflow | ยาก | ✓ มี UI ให้ |
| ตรวจจับ regression | ✗ ไม่มี | ✓ แจ้งเตือนได้ |
| Self-hosted ไม่ต้องพึ่ง third-party SaaS | ✓ ได้ | ✓ ได้ |
🐛 วิธี Debug CI4 เบื้องต้น (ก่อนใช้ DEX)
ก่อนจะพูดถึง DEX เพิ่มเติม มาทบทวนเทคนิค debug พื้นฐานใน CI4 กันก่อนครับ สำหรับมือใหม่ที่เพิ่งเริ่มต้น
1. เปิด Display Errors ใน Development
// ใน app/Config/Boot/development.php
ini_set('display_errors', '1');
error_reporting(E_ALL);⚠️ สำคัญ: อย่าเปิด display_errors ใน production เด็ดขาดครับ เพราะจะทำให้ข้อมูล internal ของระบบโชว์ให้ผู้ใช้เห็นได้
2. ใช้ var_dump() และ die() สำหรับ Quick Debug
// ใน Controller
public function checkout()
{
$cart = $this->cartModel->getCart(session()->get('user_id'));
// Debug ชั่วคราว — ดูว่า cart มีข้อมูลอะไรบ้าง
var_dump($cart);
die();
// ... โค้ดที่เหลือ
}3. ใช้ log_message() สำหรับ Production Debug
// บันทึก log พร้อม context
log_message('error', 'Checkout failed for user_id: ' . $userId);
log_message('debug', 'Cart data: ' . json_encode($cart));
log_message('info', 'Payment attempt at: ' . date('Y-m-d H:i:s'));4. ใช้ CI4 Debug Toolbar
CI4 มี built-in Debug Toolbar ที่เปิดใช้ได้ใน development mode ใน app/Config/Toolbar.php:
// ใน app/Config/Toolbar.php
public $collectors = [
Timers::class,
Database::class, // ดู queries ที่รัน
Logs::class,
Views::class,
Cache::class,
Files::class,
Routes::class,
Events::class,
];Toolbar นี้จะโชว์ข้อมูลที่ bottom bar ของหน้า web ในขณะ develop ซึ่งมีประโยชน์มากสำหรับดู query time และ route ที่ match
🔄 Workflow การ Debug ด้วย DEX
เมื่อ DEX ติดตั้งแล้ว workflow การ debug จะเปลี่ยนไปอย่างชัดเจนครับ แทนที่จะเปิด log file แล้วค้นหาเองแบบ manual คุณจะได้ทำงานแบบนี้:
// DEX จะ capture exception โดยอัตโนมัติผ่าน Exception Handler
// ใน app/Config/Exceptions.php เพิ่ม:
use Sarutobi\Dex\Handlers\DexExceptionHandler;
public $handler = DexExceptionHandler::class;จากนั้น DEX จะบันทึก issue พร้อมกับ context ครบ ได้แก่:
- Request method, URI, headers — รู้ว่า request มาจากไหน
- Database queries timeline — เห็นว่า query ไหนช้าหรือ fail
- Issue status tracking — open ignored resolved regressed
- Occurrence count — bug นี้เกิดกี่ครั้งแล้ว
🔴 สำหรับผู้ใช้ Laravel: มี Tool ที่ใกล้เคียงกันอยู่
ถ้าคุณทำงานกับ Laravel มากกว่า CI4 ระบบ ecosystem ของ Laravel มี tool สำหรับ debug ที่ครบครันอยู่แล้วครับ ลองเปรียบเทียบดู:
| Feature | DEX (CI4) | Laravel Telescope | Laravel Debugbar |
|---|---|---|---|
| Request lifecycle | ✓ | ✓ | ✓ |
| Issue status tracking | ✓ | จำกัด | ✗ |
| Regression detection | ✓ | ✗ | ✗ |
| Production-ready | ✓ | ✓ | Dev only |
| Self-hosted | ✓ | ✓ | ✓ |
| Framework | CI4 | Laravel | Laravel |
จะเห็นว่า DEX มีจุดเด่นที่ issue status tracking และ regression detection ซึ่ง Telescope ยังทำได้ไม่เต็มที่ครับ
✅ Best Practices การ Debug PHP/CI4 อย่างมืออาชีพ
นอกจากการใช้ tool แล้ว วิธีคิดและวิธีเขียนโค้ดก็สำคัญมากครับ ขอแนะนำแนวทางปฏิบัติที่ดีที่สุดไว้ดังนี้:
1. แยก Logic ออกจาก Controller ให้ชัดเจน
// ❌ ไม่ดี — Controller ทำทุกอย่าง debug ยาก
public function createOrder()
{
$data = $this->request->getPost();
$db = db_connect();
$db->query("INSERT INTO orders ...");
// ส่ง email, update stock, log ทุกอย่างอยู่ใน method เดียว
}
// ✓ ดี — แยก concern ออกจากกัน trace ได้ง่าย
public function createOrder()
{
$data = $this->request->getPost();
$order = $this->orderService->create($data);
return $this->respond(['order_id' => $order->id]);
}2. ใส่ Try-Catch พร้อม Context ที่มีความหมาย
try {
$result = $this->paymentGateway->charge($amount, $card);
} catch (\Exception $e) {
log_message('error', 'Payment failed', [
'user_id' => $userId,
'amount' => $amount,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
throw $e; // re-throw ให้ DEX จับได้
}3. ตั้งชื่อ Route ให้สื่อความหมาย
// ใน app/Config/Routes.php
$routes->post('checkout/process', 'CheckoutController::process', [
'as' => 'checkout.process' // ชื่อ route ช่วยให้ DEX log อ่านง่าย
]);
$routes->get('order/(:num)/status', 'OrderController::status/$1', [
'as' => 'order.status'
]);🎯 สรุป
การ debug application จริงๆ ใน production ต้องการมากกว่าแค่การเปิดดู log file ครับ เราต้องการ workflow ที่ช่วยให้เราเห็นภาพรวมของ request ทั้งหมด ไม่ใช่แค่ error message เพียงบรรทัดเดียว
DEX ถูกสร้างมาเพื่อเติมช่องว่างตรงนี้ใน ecosystem ของ CodeIgniter 4 โดยเฉพาะ — ไม่ได้พยายามเป็น APM ขนาดใหญ่ แต่มุ่งเน้นที่การทำสิ่งหนึ่งสิ่งเดียวให้ดี นั่นคือ: บอกว่า CI4 request ของคุณทำอะไร ที่ไหน และทำไมมันถึงพัง
สำหรับนักพัฒนาที่ทำงานกับ business application ที่ใช้ CI4 มานานหลายปี DEX ช่วยให้การ debug กลายเป็น workflow ที่มีระเบียบ แทนที่จะเป็นการ "เดาเอา" จาก log ที่กระจัดกระจาย
ส่วนนักพัฒนา Laravel ก็ไม่ต้องน้อยใจ เพราะมี Telescope และ Debugbar รองรับอยู่แล้ว แต่ถ้าวันไหนต้องย้ายมาทำ CI4 บ้าง ลอง DEX ดูครับ — คุ้มค่าแน่นอน
🚀 พร้อมจะ Debug อย่างมืออาชีพแล้วหรือยัง?
ลอง DEX ใน CI4 project ของคุณวันนี้ หรือถ้ายังไม่มี project ลองเริ่มจาก Hello World ก็ได้ครับ — ขอแค่เริ่ม!
📖 อ่านบทความต้นฉบับ DEX 📚 CI4 Official Docs💬 มีคำถามหรืออยากแชร์ประสบการณ์ debug? ฝากไว้ใน comment ด้านล่างได้เลยครับ
บทความนี้เขียนขึ้นจาก source: DEX on dev.to · Stack Overflow CI Debug · GitHub Gist: Testing CI Apps

ความคิดเห็น
แสดงความคิดเห็น