MVC đổi Template (Bài trước)
(Bài tiếp) MVC html/json/rss

Hủy quá trình Render View

Nhiều khi bạn muốn hủy đi quá trình Render HTML trong View theo logic thông thường, thật đơn giản bạn cần trả về một HTTP Requesta từ action. Vì nếu action trả về một Response chứ không phải một ViewModel, array thì quá trình dùng template để phát sinh HTML sẽ dừng lại, và HTTP Response sẽ được chuyển ngay về cho client.

Còn một trườn hợp nữa, bạn vẫn render template, nhưng kết quả trả về luôn không chuyển nội dung vao layout. Lúc này bạn chỉ cần thiết lập $viewmodel->setTerminal(true);

Ví dụ Zend Framework trả về JSON đơn giản

Trở lại ví dụ Skeleton, bạn tạo một action tên là json trong controller IndexController của module Application, với yêu cầu dừng lại quá trình render template và trả về nội dung dữ liệu dạng json đơn giản. Bạn thêm action vào như sau:

//file: module/Application/src/Controller/IndexController.php
//...
    public function jsonAction() {
        $response = $this->getResponse();

        $response->setStatusCode(\Zend\Http\Response::STATUS_CODE_200);
        $response->getHeaders()->addHeaders(['Content-type' => 'application/json']);
        $data = [
            'name' => 'YourName',
            'age' => 30,
            'gender' => 'female'
        ];
        $response->setContent(json_encode($data));
        return $response;

    }
//...

Chạy thử với http://localhost/zf3/application/json để kiểm tra kết quả

Ví dụ ZF chỉ sử dụng template, không dùng tới layout

Trở lại ví dụ trên, bạn thêm một action tên nolayout

module/Application/src/Controller/IndexController.php

//...
public function nolayoutAction() {

    $view = new ViewModel();
    $view->setTerminal(true);

    return $view;
}

//...

Sau đó tạo template cho action nolayout, với nội dung

/view/application/index/nolayout.phtml

<!DOCTYPE html>
<html>
    <head>
        <title>This no layout</title>
    </head>

    <body>
        <h1>Xin chào!</h1>
        <p>Nội dung này không có sử dụng layout</p>
    </body>
</html>

Chạy thử với http://localhost/zf3/application/nolayout để kiểm tra kết quả

Ví dụ tạo tiện ích download file

Giả sử có các file cho phép download lưu ở thư mục '/data/download/', khi người dụng nhập đường dẫn dạng http://localhost/zf3/download?name=filename, thì sẽ cho phép tải file có tên filename trong thư mục đó.

Bước 1 - Mã Controller

Do trả về không phải là HTML mà là nội dung file, nên bạn xây dựng một controller mới tên là Download, trong nó xây dựng một action tên là down, nội dung controller đó như sau:

module/Application/src/Controller/DownloadController.php

<?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class DownloadController extends AbstractActionController
{

    public function downAction() {
        $fileName = $this->params()->fromQuery('name', '');

        // Xử lý an toàn tên file
        $fileName = str_replace("/", "", $fileName);
        $fileName = str_replace("\\", "", $fileName);

        // Thử mở file
        $path = './data/download/' . $fileName;
        if (!is_readable($path)) {
            $this->getResponse()->setStatusCode(404);
            throw new \Exception("$fileName : File not found");

            return;
        }

        $fileSize = filesize($path);

        $response = $this->getResponse();
        $headers = $response->getHeaders();
        $headers->addHeaderLine(
            "Content-type: application/octet-stream");
        $headers->addHeaderLine(
            "Content-Disposition: attachment; filename=\"" .
            $fileName . "\"");
        $headers->addHeaderLine("Content-length: $fileSize");
        $headers->addHeaderLine("Cache-control: private");

        // Write file content
        $fileContent = file_get_contents($path);
        if($fileContent!=false) {
            $response->setContent($fileContent);
        } else {
            // Set 500 Server Error status code
            $this->getResponse()->setStatusCode(500);
            return;
        }

        return $this->getResponse();

    }
}

Bước 2 - Đăng ký Controller

Thêm vào module/Application/config/module.config.php

//...
'controllers' => [
    'factories' => [
        Controller\IndexController::class => InvokableFactory::class,
        Controller\DownloadController::class => InvokableFactory::class
    ],
    ],
//...

Bước trên cho biết trong hệ thống controller có tồn tại Controller\DownloadController::class

Bước 3 - Thiết lập Route

Chi tiết về lập Route bạn sẽ nghiên cứu sau, ở đây bạn chỉ cần biết sau thao tác này thì cho phép gõ địa chỉ http://localhost/zf3/download thì gọi đến action down của controller DownloadController

Thêm vào module/Application/config/module.config.php, vào bên trong phần tử routes (có sẵn 2 phần tử con là home và application - giờ thêm downoadfileshare)

//...
    // Đoạn thêm
    'downoadfileshare' => [
        'type'    => Segment::class,
        'options' => [
            'route'    => '/download[/:action]',
            'defaults' => [
                'controller'    => Controller\DownloadController::class,
                'action'        => 'down',
            ],
        ],
    ],

//...

Giờ bạn cho một số file vào thư mục /data/download/ rồi gõ url theo cấu trúc http://localhost/zf3/download?name=tenfile để kiểm tra.


Đăng ký nhận bài viết mới
MVC đổi Template (Bài trước)
(Bài tiếp) MVC html/json/rss