[ตอนที่ 5] เวิร์คช้อป CMS อย่างง่าย เก็บข้อมูลลงฐานข้อมูล
ในบทนี้ผมจะเขียนถึงการสร้างโมดูลสมุดเยี่ยม (Guest Book) เนื่องจากผมมองว่าโมดูลสมุดเยี่ยมนี่แหละที่สามารถอธิบายความสามารถของคชสารได้หลายอย่าง ในแบบที่ไม่ซับซ้อนนัก ซึ่งถ้าเข้าใจคอนเซ็ปต์ของสมุดเยี่ยมก็สามารถพัฒนาต่อเป็นบอร์ดหรือบทความได้ไม่ยากเพราะต่างก็มีอะไรหลายๆอย่างคล้ายๆกัน เช่น
เริ่มต้นกันที่ส่วนแรก เมื่อมีการเรียกสมุดเยี่ยม จะเป็นการเรียกไปยัง Guestbook\Index\Controller ซึ่งเป็นคอนโทรลเลอร์หลักของ Guest Book นั่นเอง
เนื่องจากจริงๆแล้ว สมุดเยี่ยมจะมีเพียงหน้าเดียวแสดงรายการต่อๆกันไปเท่านั้น ดังนั้นมันจึงมีโค้ดที่ไม่ซับซ้อน
บรรทัดนี้จะเป็นการอ่านข้อมูลออกมาจากฐานข้อมูล
และข้อมูลที่ได้จะถุกส่งไปแสดงผลด้วย View และส่งผลลัพท์จาก View ไปใส่ตัวแปร detail เพื่อส่งกลับไปแสดงผล
ลองไปดูโค้ด \Guestbook\Index\Model::get()
อธิบายโค้ดทีละส่วนนะครับ
เป็นการเรียกการใช้งาน QueryBuilder เรียกตาราง guestbook
โค้ดชุดนี้บอกว่า ถ้ามีตัวแปร visited อยู่ใน URL ด้วยห้ามโหลดข้อมูลจากแคช เช่น เมื่อมีการลบข้อมูลหรือมีการเขียนสมุดเยี่ยม เพื่อให้สมุดเยี่ยมทำการโหลดข้อมูลล่าสุดมาแสดงผล (ถ้าไม่มี สามารถใช้งานแคชได้ เช่นการเรียกหน้าเพจตามปกติ)
นับจำนวน ข้อความในสมุดเยี่ยมทั้งหมด ด้วย $query->count() และกำหนดค่ารายการแสดงผลสมุดเยี่ยมต่อหนึ่งหน้า list_per_page ไว้ที่ 10 รายการต่อหน้า ค่าเหล่านี้จะใช้ส่งกลับด้วย เลยเก็บค่าไว้ที่ object $index
โค้ดด้านบนใช้คำนวณการแสดงผลรายการตามหน้าที่เลือก คำอธิบายอยู่ในโค้ดแล้ว
กำหนดข้อมูลที่ได้ใส่ลงใน Query
ส่วนบล๊อกสุดทายก็จะมีการตรวจสอบตัวแปร visited เพื่อเปิดใช้งานแคช และทำการ Query ผลลัพท์ที่ต้องการออกมาในบรรทัดสุดท้ายด้วย $query->execute(); ก่อนที่จะทำการคืนค่าตัวแปร $index ที่เก็บผลลัพท์ทั้งหมดไว้กลับไป
- สมุดเยี่ยมจะต้องมีฟอร์มสำหรับเขียนสมุดเยี่ยม ซึ่งจะมีลักษณะคล้ายๆกับการตั้งกระทู้ หรือการแสดงความคิดเห็นของบอร์ด
- สมุดเยี่ยมจะต้องมีการแสดงเนื้อหาที่เขียนในลักษณะของลิสต์รายการ คล้ายๆกับการแสดงรายการบทความ หรือการแสดงรายการความคิดเห็น
- สมุดเยี่ยมจะต้องมีการแบ่งหน้าการแสดงผล ซึ่งทั้งบอร์ดหรือบทความก็ต้องมีเช่นกัน
เริ่มต้นกันที่ส่วนแรก เมื่อมีการเรียกสมุดเยี่ยม จะเป็นการเรียกไปยัง Guestbook\Index\Controller ซึ่งเป็นคอนโทรลเลอร์หลักของ Guest Book นั่นเอง
namespace Guestbook\Index;
use \Kotchasan\Http\Request;
class Controller extends \Kotchasan\Controller
{
public function init(Request $request, $module)
{
// query ข้อมูล
$index = \Guestbook\Index\Model::get($request);
// คืนค่าข้อมูลโมดูล
return (object)array(
'module' => $module,
'title' => 'สมุดเยี่ยม',
'detail' => \Guestbook\Index\View::render($request, $index)
);
}
}
เนื่องจากจริงๆแล้ว สมุดเยี่ยมจะมีเพียงหน้าเดียวแสดงรายการต่อๆกันไปเท่านั้น ดังนั้นมันจึงมีโค้ดที่ไม่ซับซ้อน
// query ข้อมูล
$index = \Guestbook\Index\Model::get($request);
บรรทัดนี้จะเป็นการอ่านข้อมูลออกมาจากฐานข้อมูล
'detail' => \Guestbook\Index\View::render($request, $index)
และข้อมูลที่ได้จะถุกส่งไปแสดงผลด้วย View และส่งผลลัพท์จาก View ไปใส่ตัวแปร detail เพื่อส่งกลับไปแสดงผล
ลองไปดูโค้ด \Guestbook\Index\Model::get()
namespace Guestbook\Index;
use \Kotchasan\Http\Request;
class Model extends \Kotchasan\Model
{
public static function get(Request $request)
{
$model = new static;
$query = $model->db()->createQuery()->from('guestbook');
// เปิดใช้งาน cache ถ้าไม่มี $_GET[visited]
if (!$request->get('visited')->exists()) {
$query->cacheOn();
}
// จำนวน
$index = (object)array(
'list_per_page' => 10,
'total' => $query->count()
);
// ข้อมูลแบ่งหน้า
$index->page = $request->get('page')->toInt();
$index->totalpage = ceil($index->total / $index->list_per_page);
$index->page = max(1, ($index->page > $index->totalpage ? $index->totalpage : $index->page));
$index->start = $index->list_per_page * ($index->page - 1);
// query
$query->select()->order('create_date DESC')->limit($index->list_per_page, $index->start);
// เปิดใช้งาน cache ถ้าไม่มี $_GET[visited]
if (!$request->get('visited')->exists()) {
$query->cacheOn();
}
$index->items = $query->execute();
// คืนค่า
return $index;
}
}
อธิบายโค้ดทีละส่วนนะครับ
$model = new static;
$query = $model->db()->createQuery()->from('guestbook');
เป็นการเรียกการใช้งาน QueryBuilder เรียกตาราง guestbook
// เปิดใช้งาน cache ถ้าไม่มี $_GET[visited]
if (!$request->get('visited')->exists()) {
$query->cacheOn();
}
โค้ดชุดนี้บอกว่า ถ้ามีตัวแปร visited อยู่ใน URL ด้วยห้ามโหลดข้อมูลจากแคช เช่น เมื่อมีการลบข้อมูลหรือมีการเขียนสมุดเยี่ยม เพื่อให้สมุดเยี่ยมทำการโหลดข้อมูลล่าสุดมาแสดงผล (ถ้าไม่มี สามารถใช้งานแคชได้ เช่นการเรียกหน้าเพจตามปกติ)
// จำนวน
$ndex = (object)array(
'list_per_page' => 10,
'total' => $query->count()
);
นับจำนวน ข้อความในสมุดเยี่ยมทั้งหมด ด้วย $query->count() และกำหนดค่ารายการแสดงผลสมุดเยี่ยมต่อหนึ่งหน้า list_per_page ไว้ที่ 10 รายการต่อหน้า ค่าเหล่านี้จะใช้ส่งกลับด้วย เลยเก็บค่าไว้ที่ object $index
// คำนวณข้อมูลสำหรับใช้ในการแบ่งหน้า
// หน้าที่ต้องการ
$index->page = $request->get('page')->toInt();
// จำนวนหน้าทั้งหมด
$index->totalpage = ceil($index->total / $index->list_per_page);
// คำนวณหน้าที่กำลังแสดงผล เริ่มต้นที่หน้า 1 และไม่เกินจำนวนหน้าทั้งหมด
$index->page = max(1, ($index->page > $index->totalpage ? $index->totalpage : $index->page));
// รายการเริ่มต้นที่ต้องการ
$index->start = $index->list_per_page * ($index->page - 1);
โค้ดด้านบนใช้คำนวณการแสดงผลรายการตามหน้าที่เลือก คำอธิบายอยู่ในโค้ดแล้ว
// query
$query->select()->order('create_date DESC')->limit($index->list_per_page, $index->start);
กำหนดข้อมูลที่ได้ใส่ลงใน Query
- select() ไม่มีพารามิเตอร์ หมายถึง SELECT *
- order() หมายถึง ORDER BY create_date DESC
- limit() เช่น LIMIT 1,10
// เปิดใช้งาน cache ถ้าไม่มี $_GET[visited]
if (!$request->get('visited')->exists()) {
$query->cacheOn();
}
$index->items = $query->execute();
ส่วนบล๊อกสุดทายก็จะมีการตรวจสอบตัวแปร visited เพื่อเปิดใช้งานแคช และทำการ Query ผลลัพท์ที่ต้องการออกมาในบรรทัดสุดท้ายด้วย $query->execute(); ก่อนที่จะทำการคืนค่าตัวแปร $index ที่เก็บผลลัพท์ทั้งหมดไว้กลับไป