เนื้อหาตอนต่อไปนี้ เรามาทำความรู้จักกับ CodeIgniter 4
กันต่อ โดยมาดูในส่วนของ Services และ HTTP Request เบื้องต้น
เป็นทำความคุ้นเคย และให้เข้าใจการทำงานต่างๆ ของ CI4 เพิ่มเติม
จากตอนที่แล้ว สามารถทบทวนเนื้อหาตอนที่แล้วได้ที่
ข้อควรรู้เบื้องต้น เกี่ยวกับ CodeIgniter 4 http://niik.in/991
https://www.ninenik.com/content.php?arti_id=991 via @ninenik
จะเป็นการอธิบายภาพรวมเท่านั้น สามารถอ่านทำความใจเข้าคร่าวๆ ผ่านไปได้
การใช้งาน Services
ในการใช้ CI4 จะมีการใช้ core class หรือ class หลักผ่านการเรียกใช้งาน "services" เข้าใจโดยง่ายก็คือ แทนที่จะ
กำหนดการเรียกใช้ class ผ่านการกำหนดชื่อ class ตรงๆ ก็ใช้เป็นวิธีเรียกผ่านชื่อที่กำหนดด้วยรูปแบบการตั้งค่าง่ายๆ
เป็นเสมือนการสร้าง instance ของ class ที่เรีรยกใช้งาน จาก factory
ตัวอย่างเช่น เมื่อเราต้องการสร้าง instance ของ Timer class ปกติก็จะเรียกใช้งานในรูปแบบดังนี้
$timer = new \CodeIgniter\Debug\Timer();
ซึ่งรูปแบบข้างต้น ก็สามารถเรียกใช้งาน และทำงานได้เป็นปกติ แต่เมื่อใดก็ตามที่เราต้องการใช้ Timer class อื่น ที่อาจจะ
มีความสามารถเพิ่มเติมที่เราต้องการใช้ แทน class เดิม เมื่อต้องการเปลี่ยนแปลง เราก็ต้องไปไล่แก้ และกำหนดการเรียกใช้
งานในทุกๆ ไปใหม่ทั้งหมด และก็เป็นไปได้ที่จะเกิดข้อผิดพลาดเกิดขึ้นได้ ดังนั้น จึงเป็นที่มาของการใช้งานผ่าน services
โดยแทนที่จะสร้าง instance ขึ้นมาเอง เราก็ใช้วิธีให้ class ที่เป็นศูนย์กลางทำหน้าที่สร้าง instance ขึ้นมาให้ โดย class
ที่เป็นศูนย์กลางในการจัดการนี้ ก็มีรูปแบการทำงานง่ายๆ มีการกำหนด method เพื่อทำการ return ค่า shared instance ของ
class ที่เราจะใช้งานออกมาให้ ซึ่งเราสามารถเรียกใช้ในรูปแบบดังนี้
$timer = \Config\Services::timer();
เมื่อใดก็ตาม ที่เราต้องการเปลี่ยนแปลงการใช้งาน class ก็เพียงแค่ไปกำหนดค่าในไฟล์ service แค่ที่เดียว ไม่ต้องไป
ไล่แก้ไขโค้ดในส่วนต่างๆ ซึ่งยังช่วยป้องกันปัญหาการเกิด error ได้อีกด้วย
/app/Config/Services.php
ตัวช่วยเรียกใช้ฟังก์ชั่น services
นอกจากวิธีการเรียกใช้ด้วยรูปแบบข้างต้นที่อธิบายไปแล้ว เรายังไมีฟังก์ชั่นพิเศษ ที่ช่วยอำนวยความสะดวกให้เรา
สามารถเรียกใช้งาน services ในรูปแบบที่ง่ายขึ้น โดยจะมีด้วยกัน 2 แบบคือ service() และ single_service()
ฟังก์ชั่น service() จะคืนค่า instance ของ class ที่ต้องการใช้งาน มีรูปแบบง่ายๆ เพียงกำหนดชื่อ service ที่จะใช้
ค่าที่คืนออกมาจะเป็น shared instance ของ class ที่เรียกใช้ โดยหากมีการเรียกใช้หลายๆ ครั้งก็จะคืนค่าเป็น instance
ตัวเดียวกัน ตัวอย่างรูปแบบการเรียกใช้งาน จะเป็นดังนี้
$timer = service('timer');
ถ้าในการกำหนด method ในการตั้งค่าในไฟล์ /app/Config/Services.php มีการกำหนด paramter เพิ่มเติม
เราก็สามารถส่งค่าเข้าไปในขั้นตอนเรียกใช้ในลักษณะดังนี้ได้
$timer = service('timer', APPPATH.'views/');
ฟังก์ชั่น single_service() จะทำงานคล้ายๆ กับ service() แต่จะเป็นการสร้าง instance ใหม่ขึ้นมาเสมอ รูปแบบ
การใช้งานจะเป็นดังนี้
$timer = single_service('timer');
การกำหนด Services
ในการกำหนด services เพื่อใช้งาน จำเป็นที่ services class จะต้องมี interface ให้ใช้งาน ใน CI4 class ส่วนใหญ่
เกือบทั้งหมดจะมี interface มาด้วย หากต้องการจะสืบทอดหรือแทนที่ class หลัก ก็สามารถทได้โดยง่าย ดังนั้น หาก
เราต้องการใช้งาน class ใดๆ ให้ตรวจสอบว่ามี interface รองรับหรือไม่
ยกตัวอย่างใน CI4 จะมี RouterCollection class ซึ่ง implement จาก interface ที่ชื่อ RouterCollectionInterface
หากเราต้องการสร้างรูปแบบการกำหนด route เพิ่มเติม เราสามารถสร้าง class ใหม่ขึ้นมา โดย implement จาก
RouterCollectionInterface ดังนี้ได้
class MyRouter implements \CodeIgniter\Router\RouteCollectionInterface { // กำหนด method ต่างๆ }
จากนั้นก็แก้ไขในส่วนของการตั้งค่าใน /app/Config/Services.php เพื่อให้สร้าง intance สำหรับ MyRouter ในรูปแบบ
ดังนี้
public static function routes() { return new \App\Router\MyRouter(); }
การกำหนดให้รองรับ parameter เพิ่มเติม
ในกรณีที่เราต้องการเพิ่ม parameter ให้กับการเรียกใช้งาน service สามารถกำหนดได้ในลักษณะดังนี้
ยกตัวอย่างการใช้งาน renderer service เมื่อค่าเริ่มต้น เราต้องการให้ทำการหา Views ที่ path เริ่มต้นเป็น
APPPATH.views/ และสามารถเปลี่ยน path เป็นค่าใหม่ตามต้องการได้ ดังนั้นเราต้องกำหนด parameter ในขั้น
ตอนการสร้าง method เป็นดังนี้
public static function renderer($viewPath=APPPATH.'views/') { return new \CodeIgniter\View\View($viewPath); }
ในการเรียกใช้งาน renderer service หากไม่มีการกำหนด ค่า path เข้าไป จะใช้ค่าเรี่มต้นเป็นค่าที่กำหนด
ตัวอย่างการเรียกใช้งาน สมมติเราต้องการเปลี่ยน path เป็น /shared/views ก็จะเป็น
$renderer = \Config\Services::renderer('/shared/views'); // หรือกรณีเรียกใช้แบบฟังก์ชั่น services() // $renderer = service('renderer', '/shared/views');
การกำหนดแบบ shared classes
เป็นไปได้ที่ในบ้างครั้ง เราอาจจะต้องการใช้งานเพียงค่า instance เดียวจากการเรียกใช้ services ดังนั้นเพื่อ
ให้สามารถดึงค่า instance ที่เคยได้ถูกสร้างไปแล้วมาใช้งาน เราสามารถอ้างอิงได้จากคำสั่ง getSharedInstance()
และเพื่อไม่ให้ทำการสร้าง instance ใหม่ แต่ให้ใช้ค่าจาก getSharedInstance() แทน เราก็สามารถกำหนดค่าเพิ่มเติม
ในส่วนของการตั้งค่า method เป็นดังนี้ได้
class Services { public static function routes($getShared = false) { if (! $getShared) { return new \CodeIgniter\Router\RouteCollection(); } return static::getSharedInstance('routes'); } }
การใช้งาน HTTP Request
ในการใช้งาน CI4 อย่างมีประสิทธิภาพ เราจำเป็นต้องรู้เกี่ยวกับการทำงานของ HTTP Request แบะ Response
HTTP เป็นรูปแบบการเชื่อมต่อสื่อสารกันแบบข้อความระหว่างเครื่องที่เป็น Server กับ Client เมื่อบราวเซอร์ที่เครื่อง
Client ร้องขอหน้าเพจ หรือ request เพจที่ต้องการไปยัง Server ฝั่ง Server ก็จะทำการเตรียมหน้าเพจนั้นๆ และส่ง
กลับมายังบราวเซอร์เพื่อแสดงผล เคยเขียนอธิบายเกี่ยวกับ HTTP ทั้งใน ภาษา Dart และ NodeJs ไปแล้วสามารถอ่าน
ทบทวนได้
การ Request
เมื่อใดก็ตาม ที่ฝั่ง Client (web browser หรือ app ในมือถือ) ทำการ request ไปยัง Server จะมีการส่งข้อความ
จำนวนหนึ่งไปด้วย และก็จะรอการตอบกลับจาก Server หน้าตาของข้อมูลที่ถูกส่งไป จะประมาณนี้
GET / HTTP/1.1 Host codeigniter.com Accept: text/html User-Agent: Chrome/46.0.2490.80
ข้อความเหล่านี้ จะแสดงถึงส่วนของข้อมูลที่จำเป็น ที่ Client บอกไปทาง Server ว่าต้องการอะไร เช่น method ที่ใช้
(GET POST DELETE อื่นๆ เวอร์ชั่นของ HTTP ที่รองรับ อาจจะข้อมูลอื่นๆ เพิ่มเติมตามรูปแบบการเรียกใช้งาน เช่น รูปแบบ
ข้อมูลที่ต้องการ อย่างข้างต้นเป็น text/html เป็นต้น
การ Response
เมื่อฝั่ง Server ได้รับคำร้องขอหรือ Request เข้ามา ตัว Web App ก็จะนำข้อมูลที่ได้มาประมวลผล แล้วทำการส่ง output
ตอบกลับไปยัง Client ส่วนที่ตอบกลับมานี้เรียกว่า Response จะมีหน้าตาข้อมูลคร่าวๆ ประมาณนี้
HTTP/1.1 200 OK Server: nginx/1.8.0 Date: Thu, 05 Nov 2015 05:33:22 GMT Content-Type: text/html; charset=UTF-8 <html> . . . </html>
ข้อมูลการ Response จะบอก Client เกี่ยวกับเวอร์ชั่น HTTP ที่ใช้ ตามด้วยรหัสและข้อความสถานะ 200 OK ซึ่งเป็นรูปแบบ
มาตรฐานของข้อมูลที่ส่งกลับมาปกติ หรือถ้ากรณีไม่พบหน้าที่ทำการ request ก็จะมีค่ารหัสและสถานะเป็น 404 เป็นต้น
การใช้งาน Request และ Response
ใน CI4 จะใช้รูปแบบของ IncomingRequest class ในการจัดการกับ ข้อมูลที่ Request ซึ่งจะมีค่าต่างๆ ที่เกี่ยวข้อง
ดูตัวอย่างการใช้งานเบื้องต้น
use CodeIgniter\HTTP\IncomingRequest; $request = service('request'); // แสดง url path ที่ทำการ request มา (เช่น /about) $request->uri->getPath(); // รับค่าตัวแปร $_GET และ $_POST $request->getGet('foo'); $request->getPost('foo'); // รับค่าตัวแปร $_REQUEST // ซึ่งรวมไปถึงตัวแปร $_GET และ $_POST ด้วย $request->getVar('foo'); // รับค่า JSON จากการเรียกใช้งานผ่าน AJAX $request->getJSON(); // รับค่าตัวแปร SERVER $request->getServer('Host'); // รับค่า HTTP Request ในส่วนของ header $request->getHeader('host'); $request->getHeader('Content-Type'); $request->getMethod(); // รับค่า method ที่ใช้งาน เช่น GET, POST, PUT เป็นต้น
ในส่วนของ Response class จะมีรูปแบบการตอบกลับไปยัง Client ประมาณนี้
use CodeIgniter\HTTP\Response; $response = service('response'); $response->setStatusCode(Response::HTTP_OK); $response->setBody($output); $response->setHeader('Content-type', 'text/html'); $response->noCache(); // ส่งผลลัพธ์ไปแสดงที่ browser $response->send();
สำหรับเนื้อหาเกี่ยวกับ CodeIgniter 4 เบื้องต้น ที่ควรรู้ก็จะมีประมาณนี้ ในรายละเอียดลงลึกแต่ละส่วนการใช้งาน
จะได้นำเสนอในลำดับต่อๆ ไป