Tạo và vận hành dự án Zend Framework (Laminas) trên ServBay
Tổng quan
Zend Framework (nay là một phần của Laminas Project) là một framework PHP mã nguồn mở mạnh mẽ, cung cấp bộ thành phần hướng đối tượng chất lượng cao để phát triển ứng dụng web và dịch vụ hiện đại. Framework này nổi bật nhờ tính linh hoạt, kiến trúc module hóa và hiệu năng vượt trội, phù hợp xây dựng từ website đơn giản đến những ứng dụng doanh nghiệp phức tạp.
ServBay là môi trường phát triển web local dành riêng cho macOS, tích hợp sẵn PHP, nhiều máy chủ web (như Caddy, Nginx), cơ sở dữ liệu (MySQL, PostgreSQL, MongoDB), dịch vụ bộ nhớ đệm (Redis, Memcached) cùng nhiều công cụ hỗ trợ khác. Với ServBay, việc thiết lập và quản lý các phần mềm này trở nên dễ dàng, giúp bạn nhanh chóng triển khai và vận hành các dự án PHP framework ngay trên máy local.
Tài liệu này sẽ hướng dẫn bạn từng bước tạo và vận hành dự án Zend Framework (Laminas) với ServBay, đồng thời giới thiệu cách tích hợp các dịch vụ cơ sở dữ liệu và cache do ServBay cung cấp.
Yêu cầu trước
Trước khi bắt đầu, hãy đảm bảo bạn đã chuẩn bị các điều kiện sau:
- Cài đặt ServBay: Bạn đã cài đặt và chạy thành công ServBay trên macOS. Nếu chưa, hãy truy cập trang chủ ServBay để tải và tham khảo hướng dẫn cài đặt.
- Các gói phần mềm trong ServBay: Đảm bảo các thành phần cần thiết đã được cài đặt và kích hoạt trong ServBay, bao gồm:
- Ít nhất một phiên bản PHP (khuyến khích PHP 8.x trở lên vì các phiên bản mới của Zend Framework / Laminas yêu cầu phiên bản PHP cao).
- Máy chủ web (Caddy hoặc Nginx).
- Composer (ServBay thường cài sẵn).
- Các dịch vụ cơ sở dữ liệu (MySQL, PostgreSQL) và bộ nhớ đệm bạn dự định sử dụng (Memcached, Redis). Bạn có thể dễ dàng bật/tắt các dịch vụ này trong bảng điều khiển ServBay.
Tạo dự án Zend Framework
ServBay khuyến nghị bạn đặt toàn bộ mã nguồn dự án trong thư mục /Applications/ServBay/www
nhằm giúp tiện quản lý và tự động cấu hình khi cài đặt website.
Truy cập thư mục gốc web
Mở Terminal, chuyển đến thư mục gốc web do ServBay khuyến nghị:
bashcd /Applications/ServBay/www
1Khởi tạo dự án bằng Composer
Composer đã được tích hợp sẵn trong ServBay nên bạn không cần cài đặt thêm. Dùng lệnh
create-project
của Composer để tạo bộ khung Zend Framework (Laminas skeleton application) trong thư mụcservbay-zend-app
:bashcomposer create-project laminas/laminas-skeleton-application servbay-zend-app
1Lệnh này sẽ tải ứng dụng mẫu của Zend Framework (Laminas) vào thư mục
servbay-zend-app
và tự động cài đặt các thư viện phụ thuộc.Truy cập thư mục dự án
Điều hướng vào thư mục dự án vừa tạo:
bashcd servbay-zend-app
1
Cấu hình máy chủ Web
Để có thể truy cập dự án Zend Framework qua trình duyệt, bạn cần cấu hình một website trong ServBay.
- Mở bảng điều khiển ServBay: Khởi động app ServBay.
- Đi tới phần Cài đặt Website: Nhấn chọn tab Website (Websites) trong bảng điều khiển.
- Thêm website mới: Bấm nút
+
phía dưới bên trái để tạo cấu hình website mới. - Điền thông tin website:
- Tên (Name): Đặt tên dễ nhớ cho website, chẳng hạn
My Zend Dev Site
. - Tên miền (Domain): Nhập tên miền bạn muốn sử dụng để truy cập dự án. Để tránh xung đột tên miền thật, nên dùng hậu tố
.local
hoặc.test
, ví dụservbay-zend-test.local
. ServBay sẽ tự động cấu hình phân giải DNS local. - Loại website (Website Type): Chọn
PHP
. - Phiên bản PHP (PHP Version): Lựa chọn phiên bản PHP mà website sử dụng (ví dụ
8.3
). Đảm bảo phiên bản này đã cài đặt và kích hoạt trong ServBay. - Thư mục gốc website (Document Root): Là thư mục cung cấp file cho máy chủ web. File vào của Zend Framework là
index.php
trong thư mụcpublic
của dự án. Vậy nên đường dẫn thư mục gốc cần trỏ tới/Applications/ServBay/www/servbay-zend-app/public
.
- Tên (Name): Đặt tên dễ nhớ cho website, chẳng hạn
- Lưu và khởi động lại: Nhấn Lưu (Save). Khi được hỏi, xác nhận áp dụng thay đổi – máy chủ web sẽ tự động tải lại cấu hình và website mới sẽ hoạt động.
Tham khảo thêm các bước cụ thể trong tài liệu Thêm website đầu tiên của ServBay.
Ví dụ cơ bản "Hello ServBay!"
Bây giờ, hãy chỉnh sửa code để khi truy cập URL gốc (/
) sẽ hiển thị dòng chữ "Hello ServBay!".
Cấu hình Route và Controller (module.config.php)
Sửa file
module/Application/config/module.config.php
tại thư mục gốc dự án. Đảm bảo file này có cấu hình route và controller như sau:php<?php declare(strict_types=1); namespace Application; use Laminas\Router\Http\Literal; use Laminas\Router\Http\Segment; use Laminas\ServiceManager\Factory\InvokableFactory; return [ 'router' => [ 'routes' => [ 'home' => [ 'type' => Literal::class, 'options' => [ 'route' => '/', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'index', ], ], ], // ... các cấu hình route khác ], ], 'controllers' => [ 'factories' => [ Controller\IndexController::class => InvokableFactory::class, ], ], 'view_manager' => [ 'display_not_found_reason' => true, 'display_exceptions' => true, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => [ 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 'application/index/index' => __DIR__ . '/../view/application/index/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', ], 'template_path_stack' => [ __DIR__ . '/../view', ], ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49Lưu ý: Đây là một phần của file
module.config.php
. Bạn cần ghép đoạn này vào mảng cấu hình sẵn có, đảm bảo route'home'
và khai báo factory choController\IndexController::class
.Tạo hoặc sửa Controller (IndexController.php)
Sửa hoặc tạo file
module/Application/src/Controller/IndexController.php
. Đảm bảo phương thứcindexAction
trả về ViewModel chứa thông báo:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class IndexController extends AbstractActionController { /** * Mặc định, hiển thị trang chào mừng. */ public function indexAction() { // Trả về ViewModel và truyền biến 'message' qua view return new ViewModel([ 'message' => 'Hello ServBay!', ]); } // ... các action khác }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24Tạo hoặc sửa view file (index.phtml)
Sửa hoặc tạo file
module/Application/view/application/index/index.phtml
để nhận biếnmessage
từ controller và hiển thị:php<h1><?php echo $this->message; ?></h1>
1Ở đây dùng trợ lý view
$this->message
của Zend Framework (Laminas) để nhận dữ liệu từ controller.
Truy cập website
Mở trình duyệt và nhập tên miền bạn đã cấu hình trên ServBay, ví dụ https://servbay-zend-test.local
.
Nếu mọi cấu hình đều đúng, bạn sẽ thấy dòng chữ Hello ServBay!
. Điều này xác nhận rằng dự án Zend Framework đã chạy thành công trên ServBay.
Ví dụ tích hợp cơ sở dữ liệu và cache
ServBay hỗ trợ nhiều cơ sở dữ liệu và dịch vụ bộ nhớ đệm đa dạng. Sau đây là các ví dụ minh họa cách Zend Framework sử dụng Memcached, Redis, MySQL và PostgreSQL trong dự án.
Lưu ý quan trọng: Mỗi ví dụ về database/cache dưới đây là độc lập. Trong thực tế bạn chỉ dùng loại database và một hoặc nhiều dịch vụ cache phù hợp với nhu cầu. Đảm bảo các dịch vụ (MySQL, PostgreSQL, Memcached, Redis) đã khởi động trong ServBay trước khi chạy thử các ví dụ.
Ví dụ thao tác với cơ sở dữ liệu – Tạo bảng
Trước tiên, chúng ta thử thao tác với database qua component Laminas DB, tạo nhanh một bảng đơn giản. Đoạn code bên dưới minh họa cách định nghĩa lệnh tạo bảng và thực thi thủ công (không sử dụng đầy đủ công cụ Migrations của Laminas).
Cài đặt component Laminas DB
Cài đặt Laminas DB bằng Composer ở thư mục gốc dự án:
bashcomposer require laminas/laminas-db
1Tạo database thủ công
Trước khi thực hiện ví dụ, hãy tạo database có tên
servbay_zend_app
trong dịch vụ database bạn sử dụng trên ServBay. Bạn có thể thao tác qua các công cụ quản lý như phpMyAdmin (MySQL), pgAdmin (PostgreSQL), MongoDB Compass... Trên ServBay, tên đăng nhập mặc định cho MySQL/MariaDB làroot
và mật khẩu làpassword
; PostgreSQL cũng sử dụngroot/password
.Định nghĩa và thực thi lệnh tạo bảng (ví dụ)
Tạo file PHP (ví dụ:
create_users_table.php
tại thư mục gốc hoặc tạm thời), với nội dung:php<?php // create_users_table.php use Laminas\Db\Adapter\Adapter; use Laminas\Db\Sql\Sql; // Giả sử bạn dùng MySQL hoặc MariaDB $adapter = new Adapter([ 'driver' => 'Pdo_Mysql', // hoặc 'Pdo_Pgsql' 'database' => 'servbay_zend_app', 'username' => 'root', 'password' => 'password', // Mật khẩu mặc định ServBay 'hostname' => '127.0.0.1', // 'port' => 3306, // Cổng mặc định MySQL // 'port' => 5432, // Cổng mặc định PostgreSQL ]); $sql = new Sql($adapter); // Định nghĩa lệnh tạo bảng users $create = $sql->createTable('users') ->addColumn(new \Laminas\Db\Sql\Ddl\Column\Integer('id', false, null, ['AUTO_INCREMENT' => true])) ->addColumn(new \Laminas\Db\Sql\Ddl\Column\Varchar('name', 255)) ->addColumn(new \Laminas\Db\Sql\Ddl\Column\Varchar('email', 255, ['UNIQUE' => true])) ->addConstraint(new \Laminas\Db\Sql\Ddl\Constraint\PrimaryKey('id')); echo "Executing SQL:\n"; echo $sql->buildSqlString($create, $adapter->getPlatform()) . "\n"; try { // Thực thi lệnh SQL $adapter->query( $sql->buildSqlString($create, $adapter->getPlatform()), Adapter::QUERY_MODE_EXECUTE ); echo "Table 'users' created successfully.\n"; } catch (\Exception $e) { echo "Error creating table: " . $e->getMessage() . "\n"; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38Lưu ý: Đây chỉ là ví dụ tạo bảng thủ công. Trong thực tế, bạn nên quản lý schema bằng công cụ Migrations.
Chạy file này qua dòng lệnh để tạo bảng (ở ngoài hoặc trong thư mục dự án):
bashphp create_users_table.php
1
Ví dụ tích hợp MySQL
Hướng dẫn kết nối và truy vấn MySQL trong controller của Zend Framework.
Cấu hình kết nối MySQL
Sửa file
config/autoload/global.php
, cập nhật hoặc thêm cấu hình:php<?php // config/autoload/global.php return [ 'db' => [ 'driver' => 'Pdo_Mysql', 'database' => 'servbay_zend_app', // Đảm bảo database đã tồn tại 'username' => 'root', // User mặc định 'password' => 'password', // Mật khẩu mặc định 'hostname' => '127.0.0.1', 'port' => 3306, // Cổng mặc định MySQL 'charset' => 'utf8mb4', ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14Cấu hình factory cho Controller (module.config.php)
Để inject
Laminas\Db\Adapter\Adapter
vào controller, cần khai báo factory choIndexController
. Sửa mảngcontrollers
trongmodule/Application/config/module.config.php
, thayInvokableFactory
bằng:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\ServiceManager\Factory\InvokableFactory; // Giữ lại nếu đang dùng ở nơi khác use Laminas\Db\Adapter\AdapterInterface; return [ // ... các cấu hình khác 'controllers' => [ 'factories' => [ Controller\IndexController::class => function($container) { // Lấy adapter từ Service Manager $adapter = $container->get(AdapterInterface::class); // Trả về instance đã inject adapter return new Controller\IndexController($adapter); }, // Thêm factory cho controller khác nếu cần ], ], 'service_manager' => [ 'aliases' => [ // Đặt biệt danh cho AdapterInterface AdapterInterface::class => 'Laminas\Db\Adapter\Adapter', ], 'factories' => [ // Đặt factory cho Adapter 'Laminas\Db\Adapter\Adapter' => \Laminas\Db\Adapter\AdapterServiceFactory::class, ], ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32Lưu ý: Cần tích hợp đoạn này vào mảng cấu hình sẵn có. Đảm bảo phần
service_manager
đã cấu hình alias và factory như trên.Cấu hình route cho MySQL (module.config.php)
Thêm các route mới cho ví dụ MySQL vào
module/Application/config/module.config.php
:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; // ... các use khác return [ 'router' => [ 'routes' => [ // ... các route hiện tại (vd: 'home') 'mysql-add' => [ 'type' => Literal::class, 'options' => [ 'route' => '/mysql-add', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'mysqlAdd', ], ], ], 'mysql' => [ 'type' => Literal::class, 'options' => [ 'route' => '/mysql', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'mysql', ], ], ], ], ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35Thêm vào mảng route
'routes'
.Bổ sung method trong Controller (IndexController.php)
Sửa file
module/Application/src/Controller/IndexController.php
để thêm constructor nhậnAdapter
, cùng hai phương thức sau:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Sql\Sql; class IndexController extends AbstractActionController { private $adapter; // Thuộc tính lưu adapter // Nhận adapter qua constructor public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; } /** * Mặc định - trang welcome. */ public function indexAction() { return new ViewModel([ 'message' => 'Hello ServBay!', ]); } /** * Thêm user vào bảng 'users' qua MySQL. */ public function mysqlAddAction() { $sql = new Sql($this->adapter); $insert = $sql->insert('users') ->values([ 'name' => 'ServBay Demo User', 'email' => '[email protected]', ]); $statement = $sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); $message = $result->getAffectedRows() > 0 ? 'MySQL User added successfully.' : 'Failed to add MySQL user.'; return new ViewModel([ 'message' => $message, ]); } /** * Lấy toàn bộ user từ bảng 'users' qua MySQL. */ public function mysqlAction() { $sql = new Sql($this->adapter); $select = $sql->select('users'); $statement = $sql->prepareStatementForSqlObject($select); $result = $statement->execute(); $users = []; foreach ($result as $row) { $users[] = $row; } // Truyền danh sách user dưới dạng JSON cho view return new ViewModel([ 'users' => json_encode($users, JSON_PRETTY_PRINT), ]); } // ... các method khác }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77Tạo view cho MySQL
Tạo file
module/Application/view/application/index/mysql-add.phtml
:php<h1><?php echo $this->message; ?></h1>
1Tạo file
module/Application/view/application/index/mysql.phtml
:php<h1>MySQL Users</h1> <pre><?php echo $this->users; ?></pre>
1
2Truy cập ví dụ MySQL
Đảm bảo dịch vụ MySQL đã khởi động trong ServBay. Đầu tiên truy cập
https://servbay-zend-test.local/mysql-add
để thêm user mới. Bạn sẽ thấy thông báo "MySQL User added successfully." Tiếp theo truy cậphttps://servbay-zend-test.local/mysql
để xem danh sách user dưới dạng JSON.
Ví dụ tích hợp PostgreSQL
Minh họa cách kết nối và truy vấn PostgreSQL trong Zend Framework.
Cấu hình kết nối PostgreSQL
Sửa file
config/autoload/global.php
, khai báo thông tin sau (nếu bạn muốn chạy song song cả MySQL và PostgreSQL sẽ cần config nâng cao hơn, ở đây giả định chỉ dùng PostgreSQL cho thử nghiệm):php<?php // config/autoload/global.php return [ 'db' => [ 'driver' => 'Pdo_Pgsql', 'database' => 'servbay_zend_app', 'username' => 'root', 'password' => 'password', 'hostname' => '127.0.0.1', 'port' => 5432, ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13Factory cho Controller (module.config.php)
(Tương tự MySQL, bạn có thể reuse cấu hình đã làm ở trên nếu đã làm rồi).
Route cho PostgreSQL (module.config.php)
Thêm route mới vào trong
'routes'
:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; // ... các use khác return [ 'router' => [ 'routes' => [ // ... các route hiện tại (như 'home', 'mysql-add', ...) 'pgsql-add' => [ 'type' => Literal::class, 'options' => [ 'route' => '/pgsql-add', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'pgsqlAdd', ], ], ], 'pgsql' => [ 'type' => Literal::class, 'options' => [ 'route' => '/pgsql', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'pgsql', ], ], ], ], ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35Bổ sung method cho Controller (IndexController.php)
Thêm hai phương thức vào class
IndexController
:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Laminas\Db\Adapter\AdapterInterface; use Laminas\Db\Sql\Sql; class IndexController extends AbstractActionController { private $adapter; public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; } // ... các action hiện có /** * Thêm user vào bảng 'users' qua PostgreSQL. */ public function pgsqlAddAction() { $sql = new Sql($this->adapter); $insert = $sql->insert('users') ->values([ 'name' => 'ServBay Demo User', 'email' => '[email protected]', ]); $statement = $sql->prepareStatementForSqlObject($insert); $result = $statement->execute(); $message = $result->getAffectedRows() > 0 ? 'PostgreSQL User added successfully.' : 'Failed to add PostgreSQL user.'; return new ViewModel([ 'message' => $message, ]); } /** * Lấy toàn bộ user từ bảng 'users' qua PostgreSQL. */ public function pgsqlAction() { $sql = new Sql($this->adapter); $select = $sql->select('users'); $statement = $sql->prepareStatementForSqlObject($select); $result = $statement->execute(); $users = []; foreach ($result as $row) { $users[] = $row; } // Chuyển kết quả thành chuỗi JSON truyền cho view return new ViewModel([ 'users' => json_encode($users, JSON_PRETTY_PRINT), ]); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66Tạo view cho PostgreSQL
Tạo file
module/Application/view/application/index/pgsql-add.phtml
:php<h1><?php echo $this->message; ?></h1>
1Tạo file
module/Application/view/application/index/pgsql.phtml
:php<h1>PostgreSQL Users</h1> <pre><?php echo $this->users; ?></pre>
1
2Truy cập ví dụ PostgreSQL
Đảm bảo đã bật dịch vụ PostgreSQL. Trước tiên truy cập
https://servbay-zend-test.local/pgsql-add
để thêm user mẫu, nhận thông báo "PostgreSQL User added successfully." Truy cập tiếphttps://servbay-zend-test.local/pgsql
để xem dữ liệu (dưới dạng JSON).
Ví dụ tích hợp Memcached
Trình bày cách dùng Memcached để cache dữ liệu trong controller Zend Framework.
Cài đặt adapter Memcached
Sửa file
composer.json
để thêm:json// composer.json { "require": { "laminas/laminas-skeleton-application": "^1.0", "laminas/laminas-cache-storage-adapter-memcached": "^2.0" // ... các phụ thuộc khác }, // ... các cấu hình khác }
1
2
3
4
5
6
7
8
9Sau đó chạy lệnh cài đặt:
bashcomposer update
1ServBay đã tích hợp sẵn extension PHP
memcached
.Cấu hình route cho Memcached (module.config.php)
Thêm route sau vào mảng
'routes'
:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; return [ 'router' => [ 'routes' => [ // ... route hiện có 'memcached' => [ 'type' => Literal::class, 'options' => [ 'route' => '/memcached', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'memcached', ], ], ], ], ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24Bổ sung method vào Controller (IndexController.php)
Thêm phương thức sau:
php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Laminas\Cache\StorageFactory; use Laminas\Cache\Storage\StorageInterface; class IndexController extends AbstractActionController { // ... constructor và các method khác /** * Demo sử dụng Memcached. */ public function memcachedAction() { // Tạo instance Memcached // Mặc định Memcached chạy trên 127.0.0.1:11211 trong ServBay $cache = StorageFactory::factory([ 'adapter' => [ 'name' => 'memcached', 'options' => [ 'servers' => [ ['127.0.0.1', 11211], ], 'ttl' => 300, ], ], 'plugins' => [ 'serializer', 'exception_handler' => ['throw_exceptions' => false], ], ]); $cacheKey = 'my_memcached_data'; $cachedData = $cache->getItem($cacheKey, $success); if (!$success) { $cachedData = 'Hello Memcached! (Data from source, cached at ' . date('Y-m-d H:i:s') . ')'; $cache->setItem($cacheKey, $cachedData); $cachedData .= ' - CACHE MISS'; } else { $cachedData .= ' - CACHE HIT'; } return new ViewModel([ 'message' => $cachedData, ]); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54Tạo view cho Memcached
Tạo file
module/Application/view/application/index/memcached.phtml
:php<h1>Memcached Example</h1> <p><?php echo $this->message; ?></p>
1
2Truy cập ví dụ Memcached
Đảm bảo dịch vụ Memcached đang chạy. Truy cập
https://servbay-zend-test.local/memcached
. Lần đầu sẽ hiển thị thông báo có "CACHE MISS"; những lần tiếp theo trong vòng 300s sẽ thấy "CACHE HIT" (và thời gian không đổi).
Ví dụ tích hợp Redis
Hướng dẫn sử dụng Redis làm bộ nhớ đệm/dữ liệu trong Controller Zend Framework.
Cài đặt adapter Redis
Sửa file
composer.json
:json// composer.json { "require": { "laminas/laminas-skeleton-application": "^1.0", "laminas/laminas-cache-storage-adapter-redis": "^2.0", "ext-redis": "*" // ... các phụ thuộc khác }, // ... các cấu hình khác }
1
2
3
4
5
6
7
8
9
10Cài đặt:
bashcomposer update
1ServBay đã tích hợp extension
redis
sẵn.Cấu hình route cho Redis (module.config.php)
Thêm vào
'routes'
:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; return [ 'router' => [ 'routes' => [ // ... các route hiện có 'redis' => [ 'type' => Literal::class, 'options' => [ 'route' => '/redis', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'redis', ], ], ], ], ], // ... các cấu hình khác ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24Bổ sung method vào Controller (IndexController.php)
Thêm vào controller:
php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; use Laminas\Cache\StorageFactory; use Laminas\Cache\Storage\StorageInterface; class IndexController extends AbstractActionController { // ... constructor và các method khác /** * Demo sử dụng Redis. */ public function redisAction() { // Tạo instance Redis // Mặc định Redis chạy trên 127.0.0.1:6379 trong ServBay $cache = StorageFactory::factory([ 'adapter' => [ 'name' => 'redis', 'options' => [ 'server' => [ 'host' => '127.0.0.1', 'port' => 6379, // 'database' => 0, // 'password' => null, ], 'ttl' => 300, ], ], 'plugins' => [ 'serializer', 'exception_handler' => ['throw_exceptions' => false], ], ]); $cacheKey = 'my_redis_data'; $cachedData = $cache->getItem($cacheKey, $success); if (!$success) { $cachedData = 'Hello Redis! (Data from source, cached at ' . date('Y-m-d H:i:s') . ')'; $cache->setItem($cacheKey, $cachedData); $cachedData .= ' - CACHE MISS'; } else { $cachedData .= ' - CACHE HIT'; } return new ViewModel([ 'message' => $cachedData, ]); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57Tạo view cho Redis
Tạo file
module/Application/view/application/index/redis.phtml
:php<h1>Redis Example</h1> <p><?php echo $this->message; ?></p>
1
2Truy cập ví dụ Redis
Đảm bảo Redis đã khởi động trên ServBay. Truy cập
https://servbay-zend-test.local/redis
. Lần đầu bạn sẽ thấy thông báo "CACHE MISS" và các lần tiếp trong 300s sẽ là "CACHE HIT".
Tổng kết
Qua các bước trên, bạn đã biết cách tạo, cấu hình và vận hành dự án Zend Framework (Laminas) trên môi trường local ServBay. Bạn đã học cách dùng chức năng website của ServBay để cấu hình máy chủ web trỏ tới thư mục public
của dự án, cũng như cách tích hợp sử dụng các dịch vụ MySQL, PostgreSQL, Memcached và Redis của ServBay trong dự án thực tế.
ServBay giúp đơn giản hóa việc chuẩn bị môi trường phát triển local, để bạn tập trung vào viết code và phát triển sản phẩm. Tận dụng kho phần mềm phong phú và hệ thống cấu hình linh hoạt, bạn có thể mô phỏng môi trường production ngay trên máy Mac, tăng hiệu quả phát triển dự án.