在 ServBay 中创建并运行 Zend Framework (Laminas)项目
概述
Zend Framework(现称为 Laminas Project 的一部分)是一个强大的开源 PHP 框架,提供了一系列高质量、面向对象的组件,用于构建现代 Web 应用程序和服务。它以其灵活性、模块化设计和高性能而闻名,是构建从简单网站到复杂企业级应用的理想选择。
ServBay 是一个专为 macOS 设计的本地 Web 开发环境,集成了 PHP、多种 Web 服务器(如 Caddy 和 Nginx)、数据库(如 MySQL、PostgreSQL、MongoDB)、缓存服务(如 Redis、Memcached)以及其他开发工具。ServBay 提供了一个便捷的方式来配置和管理这些软件包,使得在本地搭建和运行各种 PHP 框架项目变得非常简单。
本文档将指导您如何在 ServBay 环境中创建并运行一个 Zend Framework (Laminas) 项目,并演示如何集成 ServBay 提供的数据库和缓存服务。
前提条件
在开始之前,请确保您已完成以下准备:
- 安装 ServBay: 您已经在 macOS 系统上成功安装并运行了 ServBay。如果尚未安装,请访问 ServBay 官方网站 获取下载和安装指南。
- ServBay 软件包: 确保 ServBay 中已安装并运行所需的软件包,包括:
- 至少一个 PHP 版本(建议 PHP 8.x 或更高版本,因为 Zend Framework / Laminas 的现代版本通常要求较高的 PHP 版本)。
- Web 服务器(Caddy 或 Nginx)。
- Composer (ServBay 通常自带)。
- 您计划使用的数据库服务(例如 MySQL、PostgreSQL)和缓存服务(例如 Memcached、Redis)。您可以通过 ServBay 控制面板轻松启动这些服务。
创建 Zend Framework 项目
ServBay 建议将您的网站项目统一存放在 /Applications/ServBay/www
目录下,这有助于 ServBay 自动管理和配置网站。
进入网站根目录
打开终端应用程序,导航到 ServBay 建议的网站根目录:
bashcd /Applications/ServBay/www
1使用 Composer 创建项目
ServBay 出厂时已自带 Composer,无需单独安装。使用 Composer 的
create-project
命令来创建一个新的 Zend Framework (Laminas skeleton application) 项目。我们将项目创建在一个名为servbay-zend-app
的子目录中:bashcomposer create-project laminas/laminas-skeleton-application servbay-zend-app
1这会下载 Zend Framework (Laminas) 的骨架应用程序到
servbay-zend-app
目录,并安装所有必要的依赖。进入项目目录
导航到新创建的项目目录:
bashcd servbay-zend-app
1
配置 Web 服务器
为了通过浏览器访问您的 Zend Framework 项目,您需要在 ServBay 中配置一个网站。
- 打开 ServBay 控制面板: 启动 ServBay 应用程序。
- 进入网站设置: 在 ServBay 控制面板中,找到并点击 网站 (Websites) 选项卡。
- 添加新网站: 点击左下角的
+
按钮添加一个新的网站配置。 - 填写网站信息:
- 名字 (Name): 给您的网站起一个易于识别的名字,例如
My Zend Dev Site
。 - 域名 (Domain): 输入您希望在浏览器中访问此项目的域名。为了避免与真实域名冲突,建议使用
.local
或.test
后缀的域名,例如servbay-zend-test.local
。ServBay 会自动配置本地 DNS 解析。 - 网站类型 (Website Type): 选择
PHP
。 - PHP 版本 (PHP Version): 选择您希望此网站使用的 PHP 版本(例如
8.3
)。确保该版本已在 ServBay 中安装并运行。 - 网站根目录 (Document Root): 这是 Web 服务器对外提供服务的目录。Zend Framework 的入口文件
index.php
位于项目的public
目录下。因此,网站根目录应设置为您的项目目录下的public
文件夹:/Applications/ServBay/www/servbay-zend-app/public
。
- 名字 (Name): 给您的网站起一个易于识别的名字,例如
- 保存并重启: 点击 保存 (Save) 按钮。ServBay 会提示您应用更改,点击确认后,Web 服务器将重新加载配置,使新网站生效。
详细设置步骤请参考 ServBay 文档中关于 添加第一个网站 的章节。
基本 "Hello ServBay!" 示例
现在,我们来修改项目代码,使其在访问根 URL (/
) 时输出 "Hello ServBay!"。
配置路由和控制器 (module.config.php)
编辑项目根目录下的
module/Application/config/module.config.php
文件。确保该文件包含以下基本的路由和控制器配置: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', ], ], ], // ... 其他路由配置 ], ], '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', ], ], // ... 其他配置 ];
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注意: 上述代码块是
module.config.php
的部分内容,您需要将其合并到文件中已有的配置数组中。确保'home'
路由和Controller\IndexController::class
的工厂定义存在。创建或修改控制器 (IndexController.php)
编辑或创建文件
module/Application/src/Controller/IndexController.php
。确保indexAction
方法返回一个包含消息的 ViewModel:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class IndexController extends AbstractActionController { /** * Default action to display the welcome page. */ public function indexAction() { // 返回一个 ViewModel,并将 'message' 变量传递给视图 return new ViewModel([ 'message' => 'Hello ServBay!', ]); } // ... 其他 action 方法 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24创建或修改视图文件 (index.phtml)
编辑或创建文件
module/Application/view/application/index/index.phtml
。该文件将接收控制器传递的message
变量并显示它:php<h1><?php echo $this->message; ?></h1>
1这里使用了 Zend Framework (Laminas) 的视图助手
$this->message
来访问控制器中传递的数据。
访问网站
打开您的 Web 浏览器,访问您在 ServBay 中配置的域名,例如 https://servbay-zend-test.local
。
如果一切配置正确,您应该会看到页面显示 Hello ServBay!
。这表明您的 Zend Framework 项目已成功在 ServBay 中运行。
数据库和缓存集成示例
ServBay 提供了多种数据库和缓存服务。以下示例演示如何在 Zend Framework 项目中连接并使用 Memcached, Redis, MySQL 和 PostgreSQL。
重要提示: 以下数据库和缓存示例是独立的演示。在实际应用中,您通常会根据项目需求选择一种数据库和一种或多种缓存服务,并使用依赖注入等方式管理连接。运行这些示例需要您在 ServBay 中启动相应的软件包(例如 MySQL、PostgreSQL、Memcached、Redis)。
数据库交互示例 - 创建表
我们首先演示如何使用 Laminas DB 组件与数据库进行交互,包括创建一个简单的表。这里的代码片段展示了如何定义一个表创建操作并手动执行它,而不是使用完整的 Laminas Migrations 工具。
安装 Laminas DB 组件
在项目根目录下使用 Composer 安装 Laminas DB 组件:
bashcomposer require laminas/laminas-db
1手动创建数据库
在运行数据库示例之前,您需要在 ServBay 对应的数据库服务中手动创建一个名为
servbay_zend_app
的数据库。您可以通过 ServBay 控制面板访问数据库管理工具(如 phpMyAdmin, pgAdmin, MongoDB Compass 等)来完成此操作。ServBay 中 MySQL/MariaDB 的默认用户名是root
,默认密码是password
。PostgreSQL 的默认用户名是root
,默认密码也是password
。定义并执行表创建脚本 (示例)
创建一个 PHP 文件(例如
create_users_table.php
,放在项目根目录或一个临时的位置),包含以下代码来定义并执行一个users
表的创建:php<?php // create_users_table.php use Laminas\Db\Adapter\Adapter; use Laminas\Db\Sql\Sql; // 假设您正在使用 MySQL 或 MariaDB $adapter = new Adapter([ 'driver' => 'Pdo_Mysql', // 或 'Pdo_Pgsql' 'database' => 'servbay_zend_app', 'username' => 'root', 'password' => 'password', // ServBay 默认密码 'hostname' => '127.0.0.1', // 'port' => 3306, // MySQL 默认端口 // 'port' => 5432, // PostgreSQL 默认端口 ]); $sql = new Sql($adapter); // 定义创建 users 表的 SQL $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 { // 执行 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
38注意: 这只是一个手动执行的示例脚本。在实际应用中,您会使用 Laminas Migrations 工具来管理数据库 schema 的版本。
您可以在终端中通过 PHP CLI 执行此脚本来创建表(确保在项目根目录或知道脚本路径):
bashphp create_users_table.php
1
MySQL 集成示例
演示如何在 Zend Framework 控制器中连接并查询 MySQL 数据库。
配置数据库连接
编辑
config/autoload/global.php
文件,配置 MySQL 连接信息。如果文件中已有db
配置,请修改它;如果没有,请添加:php<?php // config/autoload/global.php return [ 'db' => [ 'driver' => 'Pdo_Mysql', 'database' => 'servbay_zend_app', // 确保此数据库已存在 'username' => 'root', // ServBay 默认用户名 'password' => 'password', // ServBay 默认密码 'hostname' => '127.0.0.1', 'port' => 3306, // MySQL 默认端口 'charset' => 'utf8mb4', ], // ... 其他全局配置 ];
1
2
3
4
5
6
7
8
9
10
11
12
13
14配置控制器工厂 (module.config.php)
为了在控制器中注入
Laminas\Db\Adapter\Adapter
,您需要为IndexController
定义一个工厂。修改module/Application/config/module.config.php
文件中的controllers
部分,添加一个工厂定义。如果您已经为IndexController
定义了InvokableFactory
,请将其替换为以下工厂:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\ServiceManager\Factory\InvokableFactory; // 如果 InvokableFactory 还在其他地方使用,保留此 use 声明 use Laminas\Db\Adapter\AdapterInterface; // 添加此 use 声明 return [ // ... 其他配置 'controllers' => [ 'factories' => [ Controller\IndexController::class => function($container) { // 从 Service Manager 中获取数据库适配器 $adapter = $container->get(AdapterInterface::class); // 创建并返回 IndexController 实例,注入适配器 return new Controller\IndexController($adapter); }, // 如果需要,为其他控制器添加工厂 ], ], 'service_manager' => [ 'aliases' => [ // 为 Laminas\Db\Adapter\AdapterInterface 设置一个别名,指向实际的 Adapter AdapterInterface::class => 'Laminas\Db\Adapter\Adapter', ], 'factories' => [ // 定义 Laminas\Db\Adapter\Adapter 的工厂 'Laminas\Db\Adapter\Adapter' => \Laminas\Db\Adapter\AdapterServiceFactory::class, ], ], // ... 其他配置 ];
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注意: 上述代码块是
module.config.php
的部分内容,您需要将其合并到文件中已有的配置数组中。特别是service_manager
部分,确保AdapterInterface
的别名和Laminas\Db\Adapter\Adapter
的工厂已正确配置。配置路由 (module.config.php)
在
module/Application/config/module.config.php
文件中,为 MySQL 示例添加新的路由:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; // ... 其他 use 声明 return [ 'router' => [ 'routes' => [ // ... 现有路由 (如 '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', ], ], ], ], ], // ... 其他配置 (controllers, service_manager, view_manager 等) ];
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将上述路由添加到
router
数组中的'routes'
子数组里。添加控制器方法 (IndexController.php)
修改
module/Application/src/Controller/IndexController.php
文件,添加构造函数以接收注入的Adapter
,并添加mysqlAddAction
和mysqlAction
方法: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 声明 use Laminas\Db\Sql\Sql; // 添加此 use 声明 class IndexController extends AbstractActionController { private $adapter; // 添加私有属性 // 添加构造函数以接收注入的 AdapterInterface public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; } /** * Default action to display the welcome page. */ public function indexAction() { return new ViewModel([ 'message' => 'Hello ServBay!', ]); } /** * Action to add a user to the 'users' table via 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, ]); } /** * Action to fetch all users from the 'users' table via 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; } // 将结果转换为 JSON 字符串传递给视图 return new ViewModel([ 'users' => json_encode($users, JSON_PRETTY_PRINT), ]); } // ... 其他 action 方法 }
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
77
78将上述构造函数和两个方法添加到
IndexController
类中。创建视图文件
创建文件
module/Application/view/application/index/mysql-add.phtml
:php<h1><?php echo $this->message; ?></h1>
1创建文件
module/Application/view/application/index/mysql.phtml
:php<h1>MySQL Users</h1> <pre><?php echo $this->users; ?></pre>
1
2访问 MySQL 示例
确保 ServBay 中的 MySQL 服务正在运行。 首先访问
https://servbay-zend-test.local/mysql-add
来添加一个用户。您应该看到 "MySQL User added successfully." 的消息。 然后访问https://servbay-zend-test.local/mysql
来查看users
表中的数据。您应该能看到刚刚添加的用户信息(以 JSON 格式显示)。
PostgreSQL 集成示例
演示如何在 Zend Framework 控制器中连接并查询 PostgreSQL 数据库。
配置数据库连接
编辑
config/autoload/global.php
文件,配置 PostgreSQL 连接信息。注意: 如果您想同时运行 MySQL 和 PostgreSQL 示例,您可能需要更复杂的配置或使用不同的配置环境。此示例假设您将'db'
配置切换到 PostgreSQL:php<?php // config/autoload/global.php return [ 'db' => [ 'driver' => 'Pdo_Pgsql', 'database' => 'servbay_zend_app', // 确保此数据库已存在 'username' => 'root', // ServBay 默认用户名 'password' => 'password', // ServBay 默认密码 'hostname' => '127.0.0.1', 'port' => 5432, // PostgreSQL 默认端口 ], // ... 其他全局配置 ];
1
2
3
4
5
6
7
8
9
10
11
12
13配置控制器工厂 (module.config.php)
(与 MySQL 示例相同)确保
module/Application/config/module.config.php
中的controllers
和service_manager
配置正确设置了IndexController
的工厂以注入AdapterInterface
。如果您已经按照 MySQL 示例修改了,则无需再次修改此部分。配置路由 (module.config.php)
在
module/Application/config/module.config.php
文件中,为 PostgreSQL 示例添加新的路由:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; // ... 其他 use 声明 return [ 'router' => [ 'routes' => [ // ... 现有路由 (如 'home', 'mysql-add', 'mysql') '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', ], ], ], ], ], // ... 其他配置 ];
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将上述路由添加到
router
数组中的'routes'
子数组里。添加控制器方法 (IndexController.php)
修改
module/Application/src/Controller/IndexController.php
文件,添加pgsqlAddAction
和pgsqlAction
方法: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; } // ... 现有 action 方法 (如 indexAction, mysqlAddAction, mysqlAction) /** * Action to add a user to the 'users' table via 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, ]); } /** * Action to fetch all users from the 'users' table via 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; } // 将结果转换为 JSON 字符串传递给视图 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
66
67将上述两个方法添加到
IndexController
类中。创建视图文件
创建文件
module/Application/view/application/index/pgsql-add.phtml
:php<h1><?php echo $this->message; ?></h1>
1创建文件
module/Application/view/application/index/pgsql.phtml
:php<h1>PostgreSQL Users</h1> <pre><?php echo $this->users; ?></pre>
1
2访问 PostgreSQL 示例
确保 ServBay 中的 PostgreSQL 服务正在运行。 首先访问
https://servbay-zend-test.local/pgsql-add
来添加一个用户。您应该看到 "PostgreSQL User added successfully." 的消息。 然后访问https://servbay-zend-test.local/pgsql
来查看users
表中的数据。您应该能看到刚刚添加的用户信息(以 JSON 格式显示)。
Memcached 集成示例
演示如何在 Zend Framework 控制器中使用 Memcached 进行数据缓存。
安装 Memcached 适配器
在项目根目录下使用 Composer 安装 Laminas Cache 的 Memcached 存储适配器:
json// composer.json { "require": { "laminas/laminas-skeleton-application": "^1.0", "laminas/laminas-cache-storage-adapter-memcached": "^2.0" // 添加此行 // ... 其他依赖 }, // ... 其他配置 }
1
2
3
4
5
6
7
8
9然后运行
composer update
安装依赖:bashcomposer update
1ServBay 已经预装了 PHP 的
memcached
扩展,无需额外安装。配置路由 (module.config.php)
在
module/Application/config/module.config.php
文件中,为 Memcached 示例添加新的路由:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; // ... 其他 use 声明 return [ 'router' => [ 'routes' => [ // ... 现有路由 'memcached' => [ 'type' => Literal::class, 'options' => [ 'route' => '/memcached', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'memcached', ], ], ], ], ], // ... 其他配置 ];
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将上述路由添加到
router
数组中的'routes'
子数组里。添加控制器方法 (IndexController.php)
修改
module/Application/src/Controller/IndexController.php
文件,添加memcachedAction
方法:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; // ... 其他 use 声明 (如 AdapterInterface, Sql) use Laminas\Cache\StorageFactory; // 添加此 use 声明 use Laminas\Cache\Storage\StorageInterface; // 添加此 use 声明 class IndexController extends AbstractActionController { // ... 构造函数和现有 action 方法 /** * Action to demonstrate Memcached usage. */ public function memcachedAction() { // 创建 Memcached 缓存存储实例 // ServBay 的 Memcached 默认运行在 127.0.0.1:11211 $cache = StorageFactory::factory([ 'adapter' => [ 'name' => 'memcached', 'options' => [ 'servers' => [ ['127.0.0.1', 11211], ], 'ttl' => 300, // 缓存有效期 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
54
55
56
57
58将上述方法添加到
IndexController
类中。创建视图文件
创建文件
module/Application/view/application/index/memcached.phtml
:php<h1>Memcached Example</h1> <p><?php echo $this->message; ?></p>
1
2访问 Memcached 示例
确保 ServBay 中的 Memcached 服务正在运行。 访问
https://servbay-zend-test.local/memcached
。第一次访问时,您应该看到包含 "CACHE MISS" 的消息。在缓存有效期内(本例中是 300 秒)再次访问,您应该看到包含 "CACHE HIT" 的消息,并且时间戳不会更新,这表明数据是从缓存中获取的。
Redis 集成示例
演示如何在 Zend Framework 控制器中使用 Redis 进行数据缓存或存储。
安装 Redis 适配器
在项目根目录下使用 Composer 安装 Laminas Cache 的 Redis 存储适配器:
json// composer.json { "require": { "laminas/laminas-skeleton-application": "^1.0", "laminas/laminas-cache-storage-adapter-redis": "^2.0", // 添加此行 "ext-redis": "*" // 确保安装了 PHP 的 redis 扩展 // ... 其他依赖 }, // ... 其他配置 }
1
2
3
4
5
6
7
8
9
10然后运行
composer update
安装依赖:bashcomposer update
1ServBay 已经预装了 PHP 的
redis
扩展,无需额外安装。配置路由 (module.config.php)
在
module/Application/config/module.config.php
文件中,为 Redis 示例添加新的路由:php<?php // module/Application/config/module.config.php namespace Application; use Laminas\Router\Http\Literal; // ... 其他 use 声明 return [ 'router' => [ 'routes' => [ // ... 现有路由 'redis' => [ 'type' => Literal::class, 'options' => [ 'route' => '/redis', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'redis', ], ], ], ], ], // ... 其他配置 ];
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将上述路由添加到
router
数组中的'routes'
子数组里。添加控制器方法 (IndexController.php)
修改
module/Application/src/Controller/IndexController.php
文件,添加redisAction
方法:php<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; // ... 其他 use 声明 use Laminas\Cache\StorageFactory; // 如果未添加,添加此 use 声明 use Laminas\Cache\Storage\StorageInterface; // 如果未添加,添加此 use 声明 class IndexController extends AbstractActionController { // ... 构造函数和现有 action 方法 /** * Action to demonstrate Redis usage. */ public function redisAction() { // 创建 Redis 缓存存储实例 // ServBay 的 Redis 默认运行在 127.0.0.1:6379 $cache = StorageFactory::factory([ 'adapter' => [ 'name' => 'redis', 'options' => [ 'server' => [ 'host' => '127.0.0.1', 'port' => 6379, // 'database' => 0, // Redis 数据库索引 // 'password' => null, // 如果需要密码 ], 'ttl' => 300, // 缓存有效期 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
57
58
59
60
61将上述方法添加到
IndexController
类中。创建视图文件
创建文件
module/Application/view/application/index/redis.phtml
:php<h1>Redis Example</h1> <p><?php echo $this->message; ?></p>
1
2访问 Redis 示例
确保 ServBay 中的 Redis 服务正在运行。 访问
https://servbay-zend-test.local/redis
。第一次访问时,您应该看到包含 "CACHE MISS" 的消息。在缓存有效期内(本例中是 300 秒)再次访问,您应该看到包含 "CACHE HIT" 的消息,并且时间戳不会更新,这表明数据是从缓存中获取的。
总结
通过以上步骤,您已经成功地在 ServBay 本地开发环境中创建、配置并运行了一个 Zend Framework (Laminas) 项目。您学会了如何使用 ServBay 的网站功能配置 Web 服务器以指向项目的公共目录,以及如何在项目中集成和使用 ServBay 提供的 MySQL、PostgreSQL 数据库以及 Memcached、Redis 缓存服务。
ServBay 简化了本地开发环境的搭建和管理,让您可以更专注于代码编写和项目开发。利用 ServBay 丰富的软件包和灵活的配置,您可以轻松地在本地模拟生产环境,提高开发效率。