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.