เนื้อหาตอนต่อไปนี้เราจะมาดูเกี่ยวกับ Container
ส่วนจัดการเสริมเพิ่มเติมสำหรับ นำเอาโปรแกรมการทำงาน
จากภายนอก มาใช้ร่วมกับ slim หรืออาจจะเรียกว่าเป็น
dependency injection ก็ได้ ใน Slim จะรองรับ container ใน
รูปแบบ PSR-11 เช่น PHP-DI
แต่ในที่นี้เราจะใช้เป็นตัว League Container
ติดตั้ง League Container
ให้ทำการติดตั้ง League Container ผ่าน composer ดังนี้
composer require league/container
เวลาเรียกใช้จะรวมอยู่ใน autoload แล้วสามารถนำไปใช้งานได้เลย
การใช้งาน League Container
ทำการสร้าง instance สำหรับ Container และกำหนดการใช้งานร่วมกับ app จะกำหนดไว้ก่อนคำสั่ง
create() ตามตัวอย่างด้านล่าง
1 2 3 4 5 6 | // สร้าง Container โดยใช้ League Container $container = new League\Container\Container(); // กำหนดการใช้ Container สำหรับร่วมกับการสร้าง app Slim\Factory\AppFactory::setContainer( $container ); $app = AppFactory::create(); |
ต่อไปกำหนด service ที่ต้องการใช้งานเข้าไปใน container ในที่จะใช้เป็นส่วนของการทำงานร่วมกับฐาน
ข้อมูล MySQL โดยการกำหนด service จะใช้คำสั่ง add() ดังนี้
1 2 3 4 5 6 7 | // กำหนด service ให้กับ container $container ->add( 'db' , function () { $mysqli = new mysqli( "localhost" , "root" , "" , "test" ); if ( $mysqli ->connect_errno) exit (); if (! $mysqli ->set_charset( "utf8" )) exit (); return $mysqli ; }); |
เราสามารถเรียกใช้งานใน route หรือ middleware ได้ด้วยคำสั่ง $this->get() ดังนี้
1 2 3 4 5 | $app ->get( '/home' , function (Request $request , Response $response , $args ) { $db = $this ->get( 'db' ); $response ->getBody()->write( 'Welcome' ); return $response ; }); |
หรือกรณีต้องการตรวจสอบค่าก่อนว่ามีหรือไม่ ก็สามารถใช้คำสั่ง has() ดังนี้
1 2 3 4 5 6 7 | $app ->get( '/home' , function (Request $request , Response $response , $args ) { if ( $this ->has( 'db' )) { $db = $this ->get( 'db' ); } $response ->getBody()->write( 'Welcome' ); return $response ; }); |
ตัวอย่างประยุกต์การใช้งาน Container
เราจะทำการสร้าง REST API อย่างง่ายเป็นข้อมูลจังหวัดในประเทศไทย ใช้ตัวอย่างข้อมูล
จากฐานข้อมูลตามลิ้งค์นี้ http://niik.in/que_2398_6277
ไฟล์ index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | <?php use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; require __DIR__ . '/./vendor/autoload.php' ; // สร้าง Container โดยใช้ League Container $container = new League\Container\Container(); // กำหนดการใช้ Container สำหรับร่วมกับการสร้าง app Slim\Factory\AppFactory::setContainer( $container ); $app = AppFactory::create(); $app ->setBasePath( '/demo/api' ); // กำหนด service ให้กับ container $container ->add( 'db' , function () { $mysqli = new mysqli( "localhost" , "root" , "" , "test" ); if ( $mysqli ->connect_errno) exit (); if (! $mysqli ->set_charset( "utf8" )) exit (); return $mysqli ; }); // กำหนดรุปแบบ Error Handler เอง $customErrorHandler = function ( ServerRequestInterface $request , Throwable $exception , bool $displayErrorDetails , bool $logErrors , bool $logErrorDetails , ?LoggerInterface $logger = null ) use ( $app ) { $payload = [ 'error' => $exception ->getMessage()]; $response = $app ->getResponseFactory()->createResponse(); $response ->getBody()->write( json_encode( $payload , JSON_UNESCAPED_UNICODE) ); return $response ->withHeader( 'Content-Type' , 'application/json' ); }; // Error Middleware $errorMiddleware = $app ->addErrorMiddleware(false, true, true); $errorMiddleware ->setDefaultErrorHandler( $customErrorHandler ); // เรียกใช้งานรูปแบบที่กำหนด // Routing $app ->get( '/province[/{id:[[:digit:]]+}]' , function (Request $request , Response $response , $args ) { $data = []; if ( $this ->has( 'db' )) { $db = $this ->get( 'db' ); $sql = " SELECT * FROM tbl_provinces WHERE 1 "; if (isset( $args [ 'id' ])){ // ถ้าระบุ id จังหวัด $sql .= " AND province_id='" .(int) $args ['id ']."' "; } $result = $db ->query( $sql ); if ( $result && $result ->num_rows > 0 ){ $data = $result ->fetch_all(MYSQLI_ASSOC); } } $payload = json_encode( $data ); $response ->getBody()->write( $payload ); return $response ->withHeader( 'Content-Type' , 'application/json' ); }); $app ->run(); |
ในตัวอย่างเราใช้งาน container สำหรับสร้าง service ที่เชื่อมต่อกับฐานข้อมูล จากนั้นเรียกใช้งานใน route
ทำการดึงข้อมูลจากฐานข้อมูล แล้วส่งออกเป็นข้อมูล JSON String data
เรามีการกำหนดการสร้างรูปแบบ error middleware แบบกำหนดเอง เพื่อให้แสดงข้อมูลกรณี error ในรูปแบบ
ข้อมูล JSON String data ดูตัวอย่างผลลัพธ์การทำงาน ดังนี้
ผลลัพธ์ที่ได้

แสดงข้อมูลทั้งหมด 77 จังหวัด เมื่อเรียกไปยัง /province
แสดงข้อมูลเฉพาะจังหวัด id เท่ากับ 1 /province/1
แสดงข้อมูลเฉพาะจังหวัด id เท่ากับ 77 /province/77
แสดงข้อมูลว่าง ไม่มีจังหวัด id เท่ากับ 78 /province/78
แสดง error ไม่มีหน้าที่ตรงตามที่ระบุ /province/data
เนื้อหาเกี่ยวกับ Container ที่ใช้งานร่วมกับ slim ก็จะประมาณนี้ เป็นแนวทางนำปรับไปใช้งานต่อๆ ไป
เนื้อหาตอนหน้าจะเป็นอะไรรอติดตาม