การจัดการ Response ใน Slim framework 4

เขียนเมื่อ 2 ปีก่อน โดย Ninenik Narkdee
response object slim framework php

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ response object slim framework php

ดูแล้ว 3,307 ครั้ง


จากตอนที่แล้วเราดูเกี่ยวกับ request object ใน
slim framework ไปแล้ว เนื้อหานี้มาดูต่อในส่วนของ 
response object เป็นการคืนค่า HTTP reponse กลับไปแสดง
ยังฝั่ง client เรามาดูการจัดการส่วนต่างๆ ของ response 
เช่น status headers และ body ก่อนที่ส่งค่ากลับไปแสดง
 
 

การรับค่า Response Object

    ตัวอย่างด้านล่างเป็นการรับค่า response object เข้ามาใช้งานใน route เป็น argument ตัว
ที่สองที่เรียกใช้งานในฟังก์ชั่น ที่กำหนดไว้ใน route
 
// Routing รับค่า response object ผ่านตัวแปร $response
$app->get('/home', function (Request $request, Response $response) {
    $response->getBody()->write('Welcome'); 
    return $response;
});
 
    สำหรับการใช้งานใน middleware จะใช้งานผ่าน RequestHandler ในรูปแบบดังนี้
 
$app->add(function (Request $request, RequestHandler $handler) {
    $response = $handler->handle($request);
    return $response;
});
 
    กรณีเราต้องการสร้าง response object ใหม่ขึ้นมาใช้งานสามารถกำการทำงานเป็นดังนี้ได้
 
$app->add(function (Request $request, RequestHandler $handler) use ($app) {
    // ตัว response เดิมที่ส่งต่อๆ กันมา
    $response = $handler->handle($request);
    // ตัว response ใหม่
    $response = $app->getResponseFactory()->createResponse();
    return $response;
});
 
    หรือจะเรียกใช้งาน Response class
 
use Slim\Psr7\Response;
 
    แล้วกำหนดในลักษณะด้านล่างนี้ก็ได้เหมือนกัน
 
$app->add(function (Request $request, RequestHandler $handler) {
    // ตัว response เดิมที่ส่งต่อๆ กันมา
    $response = $handler->handle($request);
    // ตัว response ใหม่
    $response = new Response();
    return $response;
});
 
 

ข้อมูล Response Status

    ทุกๆ HTTP response จะมีสถานะ หรือ status code เป็นตัวเลข ที่กำหนดรูปแบบของ response
ที่ส่งกลับไปยัง client  สถานะ 200 เป็นค่าเริ่มต้นของ response status ที่ส่งกลับ
    สามารถดูข้อมูลของ status code ด้วยคำสั่งดังนี้
 
$status = $response->getStatusCode();
// 200
 
    กรณีที่ต้องการกำหนด status code ใหม่ ก็ทำได้ดังนี้
 
$newResponse = $response->withStatus(302);
 
 

ข้อมูล Response Headers

    ทุกๆ HTTP response มี headers แต่ใน slim framework เราจะสามารถอ่านค่าข้อมูล header ของ 
response object เฉพาะค่าที่เรากำหนดเพิ่มเข้าไปเท่านั้น หากต้องการเป็น header ค่าอื่นๆ ต้องใช้ผ่าน
request object แทน ดูตัวอย่าง สองส่วนด้านล่างประกอบคำอธิบาย
 
// App middleware
$app->add(function (Request $request, RequestHandler $handler) use ($app) {
    // ตัว response เดิมที่ส่งต่อๆ กันมา
    $response = $handler->handle($request);
    $headers = $response->getHeaders();
/*     Array
    (
        [Content-Type] => Array
            (
                [0] => application/json
            )
    
    ) */
/*    foreach ($headers as $name => $values) {
        echo $name . ": " . implode(", ", $values);
    }  */   
    return $response;
});

// Routing
$app->get('/home', function (Request $request, Response $response, $args) {  
    $payload = json_encode(['hello' => 'world'], JSON_PRETTY_PRINT);
    $response->getBody()->write($payload);      
    $response = $response->withHeader('Content-Type', 'application/json');
    return $response;
});
 
    ในส่วนของ routing เรามีการกำหนด response ขึ้นมาใหม่ ด้วยการใช้คำสั่ง withHeader() แล้วกำหนด
ส่วนของ Content-Type เข้าไป เมื่อลองแสดงข้อมูล header ใน middleware ก็จะได้โครงสร้างข้อมูลเป็น
array ตามตัวอย่างในโค้ด ซึ่งมีแค่ค่าเดียวที่สามารถอ่านได้ผ่าน response object  แต่จริงๆ แล้วมีค่าอื่นๆ
ด้วย แต่ต้องเรียกผ่าน request object จึงจะเห็นค่าอื่นๆ หรือสามารถ inspect ผ่าน dev console ของ
บราวเซอร์ก็จะเห็นค่าอื่นๆ ได้เช่นกัน 
    หากเราไม่กำหนด บรรทัดนี้
 
 //   $response = $response->withHeader('Content-Type', 'application/json');
 
    นั่นแสดงว่าคำสั่งเรียกใช้งาน header ผ่าน response object ก็จะเป็น ค่าว่าง array เป็น 0 หรือก็คือไม่มี
ข้อมูล response header ที่สามารถแสดงได้
 
    การแสดง header ทั้งหมด ใช้คำสั่งดังนี้
 
$headers = $response->getHeaders();
// print_r($headers);
foreach ($headers as $name => $values) {
    echo $name . ": " . implode(", ", $values);
}
 
    การแสดงเฉพาะ header ที่ต้องการ ใช้คำสั่งดังนี้
 
$headerValueArray = $response->getHeader('Content-Type');
 
     จะเห็นข้อมูลของแต่ละ header มีได้หลายค่า คั่นด้วย , (comma) จึงคืนค่าเป็น array หาก
เราต้องการให้แสดงเป็นข้อความเดียวก็ใช้เป็นคำสั่ง
 
$headerValueString = $response->getHeaderLine('Content-Type');
 
 
    การตรวจสอบค่า header ว่ามีหรือไม่ใช้คำสั่ง
 
if ($response->hasHeader('Content-Type')) {
    // ทำคำสั่ง
}
 
    การกำหนดค่า header ใหม่ ใช้คำสั่ง
 
$newResponse = $oldResponse->withHeader('Content-type', 'application/json');
 
    กำหนดชื่อ และค่าข้อมูลใหม่ ตามต้องการ
 
    การเพิ่มค่า header ต่อเข้าไปจากค่าเดิม ใช้คำสั่ง
 
$newResponse = $oldResponse->withAddedHeader('Allow', 'PUT');
 
    ดูตัวอย่าง
 
$response = $response
->withHeader('Content-Type', 'application/json')
->withAddedHeader('Content-Type','text/html')
->withAddedHeader('Allow', 'PUT')
->withAddedHeader('Allow', 'POST');
/*
Array
(
    [Content-Type] => Array
        (
            [0] => application/json
            [1] => text/html
        )

    [Allow] => Array
        (
            [0] => PUT
            [1] => POST
        )

)
*/
 
    withAddedHeader() จะเป็นการเพิ่มค่าใหม่ต่อเข้าไปในชื่อ header เดิมที่มีอยู่แล้ว ต่างจาก 
withHeader() ที่เป็นการกำหนดค่าใหม่ให้กับชื่อ header 
 
 
    การลบ header สามารถใช้คำสั่งดังนี้
 
$newResponse = $oldResponse->withoutHeader('Allow');
 
    จะลบได้เฉพาะข้อมูล header ของ response object ที่เรากำหนดขึ้นมาใหม่เท่านั้น และจะไปใช้ค่า
เดิมที่มีแทน
 
 

ข้อมูล Response Body

    เหมือนกับรูปแบบการใช้งานในส่วนของ request body เพียงแต่ส่วนนี้จะเป็นส่วนของข้อมูลที่กำลังส่ง
ออกไปหรือข้อมูลฝั่ง response ดูตัวอย่าง
 
// Routing
$app->get('/home', function (Request $request, Response $response, $args) {  
    $response->getBody()->write('Welcome');      
    $body = $response->getBody();
    // ได้ข้อมูล stream มาไว้ในตัวแปร $body
    echo $body->getSize()."<br>"; // ขนาดข้อมูล byte ถ้าไม่รู้จักจะเป็น null
    // 7
    echo $body->tell()."<br>"; // 0 ตำแหน่งข้อมูลปัจจุบัน
    // 7
    echo $body->eof()."<br>"; // false ยังไม่สิ้นสุดข้อมูล stream 
    // false
    echo $body->isSeekable()."<br>"; // 1 หรือ true ถ้าสามารถไปยังตำแหน่งข้อมูลได้
    // 1
    // echo $body->seek(2); // ไปเาิ่มข้อมูลที่ตำแหน่งที่ 2
    $body->rewind(); // ไปเริ่มข้อมูลที่ตำแหน่ง เริ่มต้น
    // echo $body->write();
    echo $body->isReadable()."<br>"; // 1 หรือ true ถ้าสามารถอ่านได้
    // 1
    echo $body->getContents()."<br>"; // ดึงข้อมูล stream ทั้งหมดมาแสดง
    // Welcome
    echo $body->eof()."<br>"; // 1 หรือ true เพราะแสดงข้อมูลทั้งหมดจบแล้ว
    // 1
    $body->rewind(); // ไปเริ่มข้อมูลที่ตำแหน่ง เริ่มต้น
    echo $body->read(3)."<br>"; // อ่านข้อมูลมา 3 ตัวแรก
    // Wel 
    echo $body->tell()."<br>"; // 3 ตำแหน่งข้อมูลปัจจุบัน    
    // 3    
    $body->seek(2);// เลื่อนข้อมูลไปอีก 2 ตำแหน่ง
    echo $body->tell()."<br>";  // 2   ตำแหน่งข้อมูลปัจจุบัน   
    // 2   
    echo $body->read(3)."<br>"; // ดึงข้อมูล 3 ตัวเริ่มจากตำแหน่งที่ 2
    // lco
    echo $body->tell()."<br>"; // 5 ตำแหน่งปัจจุบัน
    // 5
    print_r($body->getMetadata())."<br>"; // array ข้อมูลอื่นๆ 
    // Array ( [wrapper_type] => PHP [stream_type] => TEMP [mode] => w+b 
    // [unread_bytes] => 0 [seekable] => 1 [uri] => php://temp )
    return $response;
});
 
    ข้อมูลที่เราจะส่งออกไปทาง response เป็นข้อความคำว่า 'Welcome' ขนาด 7 ตัวอักษร รูปแบบการทำงาน
ของคำสั่งต่างๆ แสดงในโค้ด สังเกตว่า ข้อมูลนี้เป้นข้อมูล stream แบบ temp หรือข้อมูลชั่วคราวก่อน
ที่จะถูกส่งออกไปแสดง ต่างจาก request ที่จะเป็นข้อมูล stream Input 
 
    เราสามารถเรียกใช้งานข้อมูล stream อื่น เพื่อส่งออกไปแสดงได้ เช่น จากไฟล์ในระบบ โดยจะใช้งาน
กับคำสั่ง withBody()  ดูตัวอย่าง การเปิดไฟล์ข้อมูล แล้วส่งออกไปกับ response
 
    ใช้งาน StreamFactory class
 
use Slim\Psr7\Factory\StreamFactory; 
 
    ตัวอย่างการใช้งานเปิดอ่านไฟล์ composer.json 
 
// Routing
$app->get('/home', function (Request $request, Response $response, $args) {  
    // $response->getBody()->write('Welcome');   
    $streamFactory = new StreamFactory();   
    $newStream = $streamFactory->createStreamFromFile("composer.json",'r');
    $response = $response
    ->withBody($newStream)
    ->withHeader('Content-type', 'application/json');
    return $response;
});
 
 

การแสดงข้อมูล JSON

    เราสามารถกำหนด response ข้อมูลไปแสดงเป็น JSON String data ได้ดังนี้
 
$data = array('name' => 'Rob', 'age' => 40);
$payload = json_encode($data);

$response->getBody()->write($payload);
return $response
          ->withHeader('Content-Type', 'application/json')
          ->withStatus(201);
 
    ในตัวอย่างเราเพิ่มการกำหนด status code เข้าไปด้วย
    แนวทางการใช้งาน ข้อมูล JSON นี้จะเป็นแนวทางที่เราจะประยุกต์เพื่อใช้กับรุปแบบ API ในลำดับต่อๆ ไป
 
 

การ Redirect

    ในกรณีที่เราต้องการเปลี่ยน url หรือลิ้งค์ไปยังหน้าใหม่ เว็บไซต์ใหม่ หรือเพจใหม่ สามารถใช้คำสั่งได้ดังนี้
 
return $response
  ->withHeader('Location', 'https://www.ninenik.com')
  ->withStatus(302);
 
 
    เนื้อหาเกี่ยวกับการใช้งาน Response object ใน Slim framework 4 ก็มีแนวทางเบื้องต้นประมาณนี้
หลายๆ เนื้อหาก็อาจจะคุ้นเคยมาบ้างแล้ว บางรูปแบบก็คล้ายกับการใช้งานกับ request object 
เนื้อหาตอนหน้าจะเป็นอะไร รอติดตาม


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



อ่านต่อที่บทความ









เนื้อหาที่เกี่ยวข้อง









URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ