Controller Plugin
Controller Plugin là một lớp mở rộng các chức năng cho tất các Controller trong ứng dụng (nếu không dùng Plugin thì các chức năng mở rộng bạn phải tự xây dựng trong một lớp cơ sở và Controller phải kế thừa lớp đó, tuy nhiên cách này rất gò bó không linh loạt trong quá trình phát triển code).
Khi bạn đăng ký Plugin Controller, các chức năng dưới cơ chế của hệ thống MVC sẽ tự động có hiệu lực đối với tất cả các controller (Controller tự động sử dụng phương thức
magic _call()
như cầu nối để gọi đến controller plugin)
Trong Zend Framework đã định nghĩa sẵn cho bạn một số Plugin Controller tiện dụng và cấu hình để chúng đã tải vào Skeleton gồm:
Plugin | Chi tiết |
---|---|
Forward |
Gọi action từ controller khác |
Params |
Giúp đọc các biến từ HTTP Request (gồm cả $_GET, $_PUT, $_FILE ...) |
Url |
Xây dựng địa chỉ URL từ controller |
Layout |
Truy cập layout của layer view. |
Identity |
Trả về định danh người truy cập website (Bạn phải xây dựng dịch vụ Authentication trước - Học sau). |
FlashMessenger |
Cho phép bạn định nghĩa một thông điệp dạng flash (thẻ): các thông báo lưu trong session sau đó hiện thị ở một page khác. |
Redirect |
Cho phép chuyển hướng tới Controller/Action khác |
PostRedirectGet |
Chuyển hướng POST request, chuyển các biến dạng POST thành GET. |
FilePostRedirectGet |
Chuyển hướng POST request, chuyển các biến dạng POST thành GET (giữ lại các file) |
Để truy cập đến Plugin trong một Controller, thật đơn giản trong các phương thức của controller chỉ việc gọi theo tên Plugin: $this->nameplugin()
Ví dụ: Mở ví dụ Skeleton ra, đọc tham số query bàng plugin params bằng cách sửa indexAction như sau:
//..\zf3\module\Application\src\Controller\IndexController.php public function indexAction() { $product = $this->Params()->fromQuery('productname', null); var_dump($product); return new ViewModel(); }
Mờ chạy thử với các URL như http://localhost/zf3/?productname=iphonex
... để xem kết quả
Sử dụng một số Plugin chuẩn
Nếu đọc thấy khó hiểu phần này có thể bỏ qua, sau này quay lại vì có một số khái niệm chưa đề cập.
Forward
Plugin này gọi một Controller/Action bằng phương thức dispatch của nó:
$foo = $this->forward()->dispatch($name, $params); //$name : tên controller //$param: mảng tham số truyền đi, các phần tử này phải chỉ ra đúng cấu trúc //controller khai báo với các loại phần tử như 'action', 'query' ...
Ví dụ thi hành Action: testAction của controller IndexController
$htmlpage = $this->forward()->dispatch('\Application\Controller\IndexController', ['action' => 'test']);
Layout
Cho phép bạn lấy đối tượng layout (chính là đối tượng ViewModel biểu diễn layout hệ thống), qua đó bạn có thiết lập một số tham số của layout dựng HTML của hệ thống MVC, như thay đổi template, như thiết lập biến truyền vào template ...
Ví dụ bạn muốn đổi Script layout mới:
$this->layout()->setTemplate('layout/newlayout');
Trong file ..\module\Application\config\module.config.php có dòng 'layout/layout'=> __DIR__ . '/../view/layout/layout.phtml' là định nghĩa template của layout gốc (file layout.phtml) có tên 'layout/layout'. Bạn có thể định nghĩa một layout khác để sử dụng mã lệnh trên như thêm vào khu vực đó: 'layout/newlayout' => 'đường-dẫn-đến-một-layout.phtml'
Params
Parms cho phép bạn truy cập vào các tài nguyên của action thông qua các phương thức như:
fromFiles($name)
: lấy file upload, nếu $name == null, trả về mảng tất cả các filefromHeader($name)
: lấy headerfromPost($name)
: lấy biến từ POSTfromQuery($name)
: lấy biến từ chuỗi query URLfromRoute($name)
: lấy biến từ phân tích Route
Các phương thức trên nếu $name == null thì trả về mảng tất cả các đối tượng phương thức lấy
Ví dụ
$this->params()->fromRoute('param', $default); // or $this->params('param', $default);
Redirect
Plugin cho phép chuyển hướng trang. Nó có một số phương thức
toRoute($route, $params, $options)
: chuyển hướng đến URL phát sinh bởi Route thông qua các tham sốtoUrl($url)
: chuyển hướng đến URLrefresh()
: nạp lại Route hiện tại
Mỗi phương thức trên có một Response trả về, bạn có thể lập tức return để chuyển hướng.
return $this->redirect()->toRoute('login-success');
Url
Plugin giúp xây dựng URL từ định nghĩa Route, bằng cách truyền các tham số tương ứng cho phương thức fromRoute
Cú pháp
fromRoute($route, array $params = [], $options = [], $reuseMatchedParams = false)
$route
: là tên Route định nghĩa trong config (tìm hiểu sau)$params
: tham số truyền theo định nghĩa route ví dụ ['tite' => 'hoc-html', id => 100]$options
: các thiết lập bổ xung, như query, force_canonical ..., ví dụ [query => ['id'=>100], 'force_canonical' => true], (force_canonical: true xây dựng full URL gồm cả phần host)$reuseMatchedParams
nếu là true, sẽ sử dụng các tham số còn của URL hiện tại xây dựng nên URL mới (ví dụ $route ...)
Tự xây dựng Controller Plugin
Một Plugin tự viết đơn giản là xây dựng một lớp kế thừa Zend\Mvc\Controller\Plugin\AbstractPlugin
, rồi đăng ký nó trong hệ thống cấu hình
Ví dụ xây dựng Plugin tên SamplePlugin
trong Skeleton
//file: \zf3\module\Application\src\Controller\Plugin\SamplePlugin.php <?php namespace Application\Controller\Plugin; use Zend\Mvc\Controller\Plugin\AbstractPlugin; class SamplePlugin extends AbstractPlugin { public function __invoke($name = null) { if ($name == null) return $this; return "Hi, ".$name; } public function sayHello($name) { return "Hello, ".$name; } }
Sau đó đăng ký, bằng cách mở module/Application/config/module.config.php, thêm vào phần tử controller_plugins với nội dung
'controller_plugins' => [ 'factories' => [ //Đăng ký Plugin, tương tự ServiceManager \Application\Controller\Plugin\SamplePlugin::class => InvokableFactory::class, ], 'aliases' => [ //Thiết lập tên tắt gọi đến Plugin 'testsample' => \Application\Controller\Plugin\SamplePlugin::class, ] ],
Bằng cách đăng ký và tên tắt như vậy, giờ trong tất cả các controller đều có thể gọi Plugin bằng phương thức $this->testsample()
Ví dụ trong IndexAction bạn cập nhật đoạn mã sau chạy để xem thử kết quả:
$greeting1 = $this->testsample("Nam"); $greeting2 = $this->testsample()->sayHello("Minh"); var_dump($greeting1, $greeting2);
Trong Plugin trên do có định nghĩa phương thức __invoke, nên có thể gọi ngay Plugin bằng $this->testsample($name)
Trong AbstractPlugin có phương thức getController() giúp bạn lấy Controller gọi Plugin.