Stratigility lúc đầu được chuyển thể từ Sencha Connect sang ngôn ngữ PHP. Nó cho phép xây dựng nên các middleware đi cùng với Zend Framework.
Giả thiết ở đây sẽ cấu hình LAM ở local chạy ứng dụng đặt tên là min với với đường dẫn URL:
http://localhost/exp/sites/min/
với folder chứa website đặt tạiC:\wamp64\www\exp\sites\min
bạn có thể cấu hình để chạy với đường dẫnhttp://localhost
Để cài đặt chuyển đến thư mục min và dùng lệnh composer:
$ composer require zendframework/zend-stratigility
Stratigility hoạt động trên cơ sở của HTTP Message theo chuẩn PSR-7 bạn nên đọc qua trước.
Để sử dụng thì stratigility cần cài thêm các gói thành phần của Zend Framework:
zend-diactoros
: triển khai mã PSR-7 HTTP
$ composer require zendframework/zend-diactoros
Tạo ứng dụng Stratigility gồm có ba bước:
- Tạo ra middleware hoặc một Middleare pipeline.
- Tạo server sử dụng middleware.
- Chỉ thị cho server lắng nghe các yêu cầu.
Ví dụ: file index.php
<?php use Zend\Stratigility\MiddlewarePipe; use Zend\Stratigility\NoopFinalHandler; use Zend\Diactoros\Server; require __DIR__ . '/vendor/autoload.php'; $app = new MiddlewarePipe(); $server = Server::createServer($app, $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES ); $server->listen(new NoopFinalHandler());
Lúc này mở http://localhost/exp/sites/min/ thì đã chạy. Tất nhiên chưa có gì hiện thị ra màn hình.
Giải thích về cấu trúc ứng dụng trên:
$app
là một đối tượng sinh ra từ MiddlewarePipe
nó tương tự như các Pipeline (Unix)
, như là chuỗi các tiến trình mà kết quả của tiến trình này là input để chạy tiến trình tiếp theo. Trong ZF thì các tiến trình nhỏ này là Middleware, nó đưa vào chuỗi bằng phương thức pipe()
.
$server
là đối tượng tượng từ Zend\Diactoros\Server
nó chuyên nhận các yêu cầu HTTP. Nó có một hàm callback ($app) để nhận yêu cầu và xử lý chuyển nó tới callback khác, sau đó trả lại response.
Sau khi tạo được $server để nó bắt đầu lắng nghe các yêu cầu gửi đến (bắt đầu chạy ứng dụng) thì gọi hàm listen. Trong hàm listen này có tham số là một callback (có thể null nếu bạn không cần), callback này được gọi cho mục đích khi không hoàn thành được các yêu cầu gửi đến (ví dụ 404 not found).
Middleware
Khái niệm về middleware xem tại: middleware. Xem đoạn code sau phát triển từ đoạn mã trên: index.php
<?php use Zend\Diactoros\Response; use Zend\Diactoros\Server; use Zend\Stratigility\MiddlewarePipe; use Zend\Stratigility\NoopFinalHandler; require __DIR__ . '/vendor/autoload.php'; $app = new MiddlewarePipe(); $app->setResponsePrototype(new Response()); $server = Server::createServer($app, $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); // Landing page $app->pipe('exp/sites/min/', function ($req, $res, $next) { if (! in_array($req->getUri()->getPath(), ['/', ''], true)) { return $next($req, $res); } $res->getBody()->write('Hello world!'); return $res; }); // Another page $app->pipe('exp/sites/min/foo', function ($req, $res, $next) { $res->getBody()->write('FOO!'); return $res; }); $app->pipe(new \Zend\Stratigility\Middleware\NotFoundHandler(new Response())); $server->listen(new NoopFinalHandler());
Theo đoạn code, có 2 middleware được tạo ra.
Đầu tiên đó là middleware cho trang chính (langding) nó lắng nghe yêu cầu từ đường dẫn url gốc /
. Có nghĩa là request gửi đến rỗng hoặc có dạng phù hợp với /
thì nó sẽ trả về một response : lời chào Hello world!
. Nếu như như URL gửi đến không phù hợp cho middleware trên, nó sẽ chuyển thông tin cho middleware tiếp theo trong ngăn xếp stack chứa các middleware.
Middleare thứ hai nhận xử lý các request gửi đến có URL phù hợp với dạng /foo
.
Nếu Request gửi đến vẫn không phù hợp với cả Middleware thứ nhất và thứ hai thì một hàm cuối cùng (final handler) được đưa vào sẽ phát ra mã tùy theo cách sử lý của bạn, ở đây là new NoopFinalHandler() không làm gì.
Bạn chạy thử với đường dẫn: http://localhost/exp/sites/min/ và http://localhost/exp/sites/min/foo để kiểm tra kết quả.
Ví dụ trên là một diễn giải middleware và pipeline.
Trong lập trình ZF với Expressive các Middleware thường được tạo bằng cách triển khai giao diện MiddlewareInterface. Rồi đưa vào pipeline.
Gắn điều kiện với lỗi 404
Nếu không có một Middleware nào xử lý request, thông thường sẽ phát sinh ra một mã HTTP 404. Stratigility cung cấp sẵn Middleware khung cho mục đích này. Thêm nó vào pipeline để sử dụng:
$app->pipe(new \Zend\Stratigility\Middleware\NotFoundHandler(new Response()));
Chú ý đó là Middleware cuối cùng trong luồng ứng dụng. Khi nó trả về respone sẽ không còn một lớp code nào được gọi.
Nếu muốn trả về theo một mẫu HTML, có thể tự viết lại.
Cách tạo Middleware
Tạo một Middleware có nghĩa là bạn cần tạo ra đối tượng tương ứng có khả năng nhận PSR-7 ServerRequest và trả về PSR-7 Response, và một hàm callback để triệu gọi tới Middleware tiếp theo trong chuỗi. Trong Middleware của bạn, sử lý nhiều hay ít request do bạn quyết định, bao gồm cả việc chuyển thông tin cho Middleware khác như thế nào. Bằng cách cho thêm đối số thứ ba $next
, middleware có thể xử lý tiếp theo bằng cách gọi đối số $next
này hoặc nếu có định nghĩa http-interop ($delegate) chuyển đến gọi nó, hoặc trả về Middleware cha đã gọi nó một response.
Khi thực hành viết code, Middleware có thể được tạo bằng nhiều cách, tùy lựa chọn:
Middleware written in this way can be any of the following:
- Closures
- Functions
- Static class methods
- PHP array callbacks
- Invokable PHP objects: (i.e., instances of classes implementing __invoke())
- Đối tượng triển khai từ
MiddlewareInterface
: khuyến nghị.
Sử dụng ServiceManager
ServiceManager là một trình chứa, trung tâm đăng ký các dịch vụ của ứng dụng. Để tích hợp vào ứng dụng:
composer require zendframework/zend-servicemanager
Cài thêm ConfigAggregator để cấu hình SM.
$ composer require zendframework/zend-config-aggregator
Có thể triển khai mã tạo đối tượng ServiceManager như sau:
Tạo thư mục config
, tạo file container.php
trong đó.
<?php use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; // Load configuration $config = require __DIR__ . '/config.php'; // Build container $container = new ServiceManager(); (new Config($config['dependencies']))->configureServiceManager($container); // Inject config $container->setService('config', $config); return $container;
Tiếp tục tạo file config.php
trong folder config đây là file chứa cấu hình tạo SM.
<?php use Zend\ConfigAggregator\ArrayProvider; use Zend\ConfigAggregator\ConfigAggregator; use Zend\ConfigAggregator\PhpFileProvider; $cacheConfig = [ 'config_cache_path' => 'data/config-cache.php', ]; $aggregator = new ConfigAggregator([ //Thêm các config khác ở đây new ArrayProvider($cacheConfig), new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'), new PhpFileProvider('config/development.config.php'), ], $cacheConfig['config_cache_path']); return $aggregator->getMergedConfig();
Tiếp tục tạo folder:/config/autoload
và tạo file: dependencies.global.php
để định nghĩa các dependency toàn cục cần nạp vào ServiceManager.
<?php return [ 'dependencies' => [ 'aliases' => [ ], 'invokables' => [ ], 'factories' => [ ], ], ];
Tại file index.php ở trên thêm vào dòng code sau trước $app để tạo ServiceManager.
$container = require 'config/container.php';
Bộ khung ứng dụng Middleware đối với ZF là : Expressive
https://github.com/zendframework/zend-expressive
Tham khảo: Sencha Connect