เนื้อหาตอนต่อไปนี้ เราจะมาเริ่มต้นสร้างหน้า
เพจเบื้องต้น เพื่อทำความเข้าใจ การช้งาน Controller
และ Views ใน CI4
สร้าง Controller แรก
ให้เราสร้างไฟล์ ตามโครงสร้างไฟล์เดอร์ดังนี้ app/Controllers/Pages.php และกำหนดโค้ดเบื้องต้นเป็น
<?php namespace App\Controllers; // กำหนด namespace use CodeIgniter\Controller; // เรียกใช้งาน Controller class class Pages extends Controller // สร้าง Pages class โดยสืบทอดจาก Controller { // ค่า index() method เรียกไฟล์ welcome_message มาแสดง public function index() { return view('welcome_message'); // คำสั่ง view() คือคำสั่งโหลดไฟล์ views (HTML) มาแสดง } // กำนหนด view() method พร้อมรับค่า argument 1 ค่า public function view($page = 'home') { } }
เราสร้าง Pages class ซึ่งสืบทอดมาจาก CodeIgniter\Controller class ดังนั้น เราสามารถเรียกใช้งาน method และ
ตัวแปรต่างๆ ที่กำหนดโดย CodeIgniter\Controller class ได้ (*system/Controller.php)
ตัว controller จะเป็นตัวศูนย์กลางการ request ใน app ของเรา
เริ่มต้นเราสร้าง method ที่ชื่อ view() สำหรับใช้ในการกำหนด template ให้กับหน้าเพจที่เราจะสร้าง ประกอบไปด้วย
ไฟล์ header.php และ footer.php ตามตำแหน่งไฟล์ดังนี้ (* โฟลเดอร์ templates ถ้ายังไม่มีก็ให้สร้างตามโครงสร้างตัวอย่าง)
ในที่นี้จะใช้ bootstrap ร่วมด้วย
app/Views/templates/header.php
<!doctype html> <html lang="th"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Document</title> <link rel="stylesheet" href="https://unpkg.com/bootstrap@4.5.0/dist/css/bootstrap.min.css" > </head> <body> <h1><?= esc($title); ?></h1>
โดยในส่วน header เรามีการเรียกใช้ตัวแปร $title พร้อมทั้งใช้ฟังก์ชั่น esc() สำหรับป้องกันการทำ XSS attacks
แน่นอนว่า เมื่อมีการเรียกใช้ตัวแปร $title แสดงว่าเราต้องทำการส่งค่าตัวแปรเข้าใน views ด้วย
app/Views/templates/footer.php
<script src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script> <script src="https://unpkg.com/bootstrap@4.5.0/dist/js/bootstrap.min.js"></script> <script type="text/javascript"> $(function(){ }); </script> </body> </html>
การกำหนดกระบวนการทำงานให้กับ Controller
เมื่อเราเตรียมในส่วนของ views เบื้องต้นแล้ว เราจะกลับมากำหนดรูปแบบการทำงานของ controller ในส่วนของ
views() method ซึ่งในเบื้องต้น เรากำหนดให้มี parameter 1 ค่า เป็นชื่อของ page ที่ต้องการโหลด ในที่นี้เราจะให้
ไฟล์ page ที่ต้องการโหลดอยู่โฟลเดอร์ app/Views/pages/ ให้เราสร้างโฟลเดอร์ pages และสร้างไฟล์ home.php
กับไฟล์ about.php โดยใส่ข้อความอะไรก็ได้ลงไปก่อน เช่น Page Home กับ Page About เป็นต้น
โครงสร้างโฟลเดอร์ไฟล์ views และ controller ที่เราจะได้ก็จะประมาณนี้
มาในส่วนของไฟล์ Pages.php หรือ Pages controller ดูในส่วนของ views() method โดยเราปรับโค้ดเพื่อกำหนด
การทำงานเพิ่มเติมเป็นดังนี้
// กำนหด view() method พร้อมรับค่า argument 1 ค่า public function view($page = 'home') { // ทำการเช็คว่าถ้าไ่ม่มีไฟล์ ตามชื่อตัวแปร $page ที่ส่งเข้ามา ให้แสดงหน้า ไม่พบไฟล์ หรือ 404 if ( ! is_file(APPPATH.'/Views/pages/'.$page.'.php')) { // จะไปเรียกไฟล์ error_404.php ในโฟลเดอร์ app/views/error/cli มาแสดง throw new \CodeIgniter\Exceptions\PageNotFoundException($page); } // กรณีมีไฟล์ ให้กำหนดตัวแปร ที่จะส่งเข้าไปใช้งานใน views ผ่านตัวแปร array $data $data['title'] = ucfirst($page); // ใช้ชื่อจากตัวแปร $page และทำเป็นตัวแรกเป็นตัวพิมพ์ใหญ่ echo view('templates/header', $data); // โหลด template ส่วน header พร้อมส่งตัวแปรเข้าไป echo view('pages/'.$page, $data); // โหลด ส่วนของ ชื่อไฟล์ที่กำหนด พร้อมส่งตัวแปรเข้าไป echo view('templates/footer', $data); // โหลด template ส่วน footer พร้อมส่งตัวแปรเข้าไป }
ทดสอบเปิดไปยังหน้าเว็บของเราตาม url ดังนี้
* หากเป็น localhost ก็จะแทนชื่อ domain เช่น https://localhost/pages
แบบที่ 1 https://www.mysslweb.com/pages แบบที่ 2 https://www.mysslweb.com/pages/index แบบที่ 3 https://www.mysslweb.com/pages/view แบบที่ 4 https://www.mysslweb.com/pages/view/home แบบที่ 5 https://www.mysslweb.com/pages/view/about แบบที่ 6 https://www.mysslweb.com/pages/view/shop
การเรียกไปยัง url ในแบบที่ 1 กับ 2 และ 3 กับ 4 จะได้ผลลัพธ์เหมือนกัน
เรามาพิจารณาในส่วนของ url กับการทำงานของ controller กัน จะได้เป็นดังนี้
http://example.com/[controller-class]/[controller-method]/[arguments]
ในส่วน แรกคือ pages เป็น controller class
ในส่วนที่สอง คือ controller-method ในแบบที่ 1 เราไม่ได้กำหนด แต่จะมีค่า defualt เป็น index() ดังนั้น
แบบที่ 1 และแบบที่ 2 จึงมีค่า controller-method เท่ากับ index() เหมือนกัน แบบที่ 3 - 6 เป็น view()
ในส่วนที่สาม คือ arguments หรือก็คือค่าที่กำหนดใน parameter ในตัวแปรชื่อ $page จะมีเฉพาะใช้งาน view()
method ดังนั้น จะมีเฉพาะในแบบที่ 3 - 6 แต่สังเกตว่าในแบบที่ 3 ไม่มีค่า arguments ดังนั้นจึงเรียกใช้ค่าเริ่มต้น
ก็คือ $page = 'home' หรือเท่ากับ home นั่นเอง ทำให้แบบที่ 3 และ 4 มีผลลัพธ์เหมือนกัน สำหรับแบบที่ 5 ก็จะ
ทำงานคล้ายแบบที่ 4 แต่ดึงไฟล์ about ตามค่า argument ที่กำหนด ในขณะที่แบบที่ 6 เมื่อเข้าสู่การตรวจสอบ
ของ controller จะพบว่า ไฟล์ shop.php ไม่มีในระบบ ดังนั้นแบบที่ 6 จึงแสดงหน้า 404 หรือไฟล์ error_404.php แทน
ดูตัวอย่างผลลัพธ์แบบที่ 3 - 6
ส่วนผลลัพธ์แบบที่ 1 และ 2 จะเป็นการดึงไฟล์ welcome_message.php หน้าเริ่มต้นของ CI4 มาแสดง
อย่างไรก็ตามรูปแบบ url ข้างต้น อาจจะมีการเปลี่ยนแปลงไปตามความซับซ้อนของการใช้งาน หรือการประยุกต์ใช้ ซึ่ง
อาจจะไม่ยืดโยงกับรูปแบบข้างต้นเสมอไป
การกำหนด Routing
เราสามารถกำหนดรุปแบบ URL ให้กับ controller และ method ในแบบที่ต้องการได้ มาดูเกี่ยวกับการตั้งค่า
สำหรับ Routes ในไฟล์ app/Config/Routes.php
/** * -------------------------------------------------------------------- * Router Setup * -------------------------------------------------------------------- */ $routes->setDefaultNamespace('App\Controllers'); $routes->setDefaultController('Home'); $routes->setDefaultMethod('index'); $routes->setTranslateURIDashes(false); $routes->set404Override(); $routes->setAutoRoute(true);
ค่าการกำหนด Route Setup เป็นการกำหนดค่าเริ่มต้นต่างๆ เราไม่จำเป็นต้องแก้ไขส่วนนี้ก็ได้ จะเห็นว่าในการใช้งาน
มีการกำหนด Namespace เริ่มต้นเป็น App\Controllers และเรียกใช้ Controller เริ่มต้นชื่อว่า Home ซึ่งเป็นไฟล์
เริ่มต้นที่มากับ CI4 อยู่แล้ว รวมถึงการกำหนด method ค่าเริ่มต้น เป็น index นั่นคือ ถ้าเราเรียกมายัง path
https://www.mysslweb.com/
จะหมายถึงการเรียกใปยัง URL
https://www.mysslweb.com/home/index นั่นเอง
ซึ่งในส่วนของการกำหนด Routes หรือ * Route Definitions ก็จะเป็นไปแนวทางเดียวกันคือ
/** * -------------------------------------------------------------------- * Route Definitions * -------------------------------------------------------------------- */ // We get a performance increase by specifying the default // route since we don't have to scan directories. $routes->get('/', 'Home::index');
เมื่อเรียกมายัง path "/" ก็ให้ใช้งาน index() method ของ Home class controller
ลองเพิ่มส่วนล่างนี้ ต่อเข้าไป จะได้เป็น
$routes->get('/', 'Home::index'); $routes->get('(:any)', 'Pages::view/$1');
ในการทำงาน CI4 จะอ่านค่าการกำหนด rule ของ routing จากบนลงล่าง ซึ่งถ้าตรงเงื่อนไขไหนก่อนก็ทำส่วนนั้น
โดยรูปแบบที่กำหนดในฝั่งซ้ายเป็นแบบ regular expression จับคู่กับฝั่งขวา ที่เรียกใช้งาน controller และ method
แยกกันด้วย "/"
รูปแบบที่เรากำหนดข้างต้น ในวงเล็บ คือค่าที่เราอ้างอิงกับค่า $1 ถ้ามีหลายวงเล็บ ก็ปรับเป็น $2 $3 เช่น
$routes->get('(:any)/(:any)/(:any)', 'Pages::view/$1/$2/$3'); // ตัวอย่าง
ดังนั้นรูปแบบข้างต้นคือ ค่าใดๆ หลัง "/" จะเป็นค่าตัวเดียวกันกับค่าในตำแหน่ง $1 นั่นก็คือค่า parameter ของ
view() method นั่นเอง ถ้าเราเรียก url ไปที่ /home ก็จะมีค่าเท่ากับ /pages/view/home ในกรณีที่ยังไม่ได้กำหนด
rule เพิ่มเข้าไป
หลังจากที่เราเพิ่ม rule เข้าไปแล้ว แนะนำให้ทำการปิดการ autoRoute เปลี่ยนค่าเป็น false
$routes->setAutoRoute(false);
เพื่อให้มั่นใจว่า การทำงานของ route จะใช้เฉพาะตามที่เรากำหนดเท่านั้น
ทดสอบเรียกไปยัง /home ผ่าน บราวเซอร์ จะได้ผลลัพธ์ดังรูป
เท่านี้ เราก็สามารถสร้าง static page หรือเว็บไซต์แบบ static ได้อย่างง่ายๆ เพียงทำการเพิ่มหน้าต่างๆ เข้าไปใน
ส่วนของ app/views/pages/