在 ServBay 中建立並運行 Webman 專案
什麼是 Webman?
Webman 是一個基於 Workerman 的高效能 PHP 非同步 Web 框架,專為建構高併發、高效能的 Web 應用而設計。與傳統的同步阻塞框架不同,Webman 採用事件驅動與非同步非阻塞 I/O 模型,在大量並發請求下表現出色。Webman 提供簡潔易用的 API 及靈活的擴充機制,非常適合開發即時應用、API 服務、微服務等。
Webman 的主要特性與優勢
- 高效能:基於 Workerman,採用事件驅動與非同步非阻塞 I/O,可處理大量併發連線,吞吐量遠超傳統同步框架。
- 易於上手:提供直觀簡易的 API 及豐富的功能,讓開發者能迅速建立應用。
- 多協定支援:原生支援 HTTP、WebSocket 等多種常用應用層協定,方便建構各類服務。
- 靈活擴充:支援透過 Composer 套件、插件與中介層機制靈活擴充框架功能。
- 低資源消耗:相較於傳統 Web 伺服器 + PHP-FPM 模式,Webman 作為常駐記憶體應用,資源開銷更低。
- 強大社群支援:擁有活躍開發者社群及豐富文件資源。
Webman 能協助開發者快速建構高效能、高可用性的 Web 應用與 API 服務,特別適合需要處理大量併發、低延遲場景。
使用 ServBay 建立並運行簡易 Webman 專案
本指南將詳細說明如何在 ServBay 本機開發環境中利用 Webman 建立並執行簡易 Web 專案。我們將演示如何安裝 Webman、編寫基本路由與控制器程式碼,以及如何整合 ServBay 提供的資料庫(MySQL、PostgreSQL)和快取服務(Redis、Memcached)。
TIP
ServBay 建議開發者將所有本機網站專案存放於 /Applications/ServBay/www
目錄下,便於 ServBay 集中管理,例如設定本機網站(原稱「主機」)。
前置條件
開始之前,請確保你已完成以下準備:
- 安裝 ServBay:你已在 macOS 成功安裝 ServBay。ServBay 提供一站式本機開發環境,內含 PHP、Composer、MySQL、PostgreSQL、Redis、Memcached 等本教學所需套件。
- 啟用所需套件:透過 ServBay 控制面板,確保以下套件已安裝並在運行中:
- 所選的 PHP 版本(建議使用較新版本,如 PHP 8.x)
- Composer(ServBay 已內建)
- MySQL
- PostgreSQL
- Redis
- Memcached
- 確認所選 PHP 版本已啟用
memcached
、redis
、pdo_mysql
、pdo_pgsql
等必要 PHP 擴充。ServBay 通常預設啟用這些常用擴充,可在 ServBay PHP 設定介面中檢查。
- 終端機操作:熟悉使用 macOS 終端機應用程式。
安裝 Webman
確認 Composer 可使用
ServBay 出廠時已預裝 Composer,可直接在終端機裏使用。你可以在終端機輸入以下命令以確認:
bashcomposer --version
1若正確顯示 Composer 版本訊息即表示 Composer 可正常使用。
進入 ServBay 網站目錄
開啟終端機,切換到 ServBay 建議的網站根目錄:
bashcd /Applications/ServBay/www
1使用 Composer 建立 Webman 專案
使用 Composer 的
create-project
命令將 Webman 框架安裝到指定目錄。我們使用servbay-webman-app
做為專案名稱:bashcomposer create-project workerman/webman servbay-webman-app
1Composer 會從 Packagist 下載 Webman 及其核心依賴至
servbay-webman-app
目錄。進入專案目錄
安裝完成後,切換到新建的專案目錄:
bashcd servbay-webman-app
1安裝必要元件
為了示範資料庫與快取功能,我們需額外安裝一些 Composer 套件。Webman 通常使用
illuminate/database
(來自 Laravel 的資料庫元件)、illuminate/redis
等。-W
參數(--with-dependencies
)協助安裝時解決相依衝突,確保相容性。bashcomposer require -W illuminate/database illuminate/redis illuminate/pagination illuminate/events symfony/var-dumper
1此命令將安裝資料庫 ORM、Redis 客戶端、分頁元件、事件調度器及用於除錯的 VarDumper。
建立資料庫及資料表
為讓範例程式碼正常運行,需在 ServBay 的 MySQL 及 PostgreSQL 資料庫建立對應的資料庫與 users
資料表。ServBay 預設資料庫 root
使用者的密碼為 password
。
你可透過 ServBay 附帶的資料庫管理工具(如 phpMyAdmin 或 pgAdmin,在 ServBay 控制面板中存取)或終端機執行下列 SQL 指令。
建立資料庫
webman_app
- MySQL:sql
CREATE DATABASE IF NOT EXISTS webman_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
1 - PostgreSQL:sql
CREATE DATABASE webman_app;
1
- MySQL:
在
webman_app
資料庫建立users
資料表- MySQL:sql
USE webman_app; CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
1
2
3
4
5
6
7 - PostgreSQL:sql
\c webman_app; -- 連線到新建立的資料庫 CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
1
2
3
4
5
6
7
- MySQL:
編寫 Web 專案程式碼
接下來,我們將新增程式碼以定義路由、建立控制器,並實現與資料庫及快取的互動邏輯。
設定路由
編輯專案根目錄下的
config/route.php
檔案,加入以下程式碼以定義範例所需路由:php<?php use Webman\Route; use app\controller\IndexController; use app\controller\CacheController; use app\controller\DatabaseController; // 定義根路徑路由,對應 IndexController 的 index 方法 Route::any('/', [IndexController::class, 'index']); // 定義快取相關路由 Route::any('/memcached', [CacheController::class, 'memcached']); Route::any('/redis', [CacheController::class, 'redis']); // 定義資料庫相關路由 Route::any('/mysql-add', [DatabaseController::class, 'mysqlAdd']); Route::any('/mysql', [DatabaseController::class, 'mysqlGet']); Route::any('/pgsql-add', [DatabaseController::class, 'pgsqlAdd']); Route::any('/pgsql', [DatabaseController::class, 'pgsqlGet']); // 可以在這裡加入更多路由...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21建立控制器檔案
在
app/controller
目錄下建立IndexController.php
、CacheController.php
及DatabaseController.php
檔案,分別加入下列程式碼。app/controller/IndexController.php
:處理根路徑請求。php<?php namespace app\controller; use support\Request; use support\Response; // 引入 Response 類 class IndexController { /** * 處理根路徑請求的範例方法 * @param Request $request 當前請求物件 * @return Response 回傳 Response 物件 */ public function index(Request $request): Response // 明確回傳型態 { // 回傳簡單的文字回應 return response('Hello ServBay & Webman!'); // 更新歡迎訊息 } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20app/controller/CacheController.php
:演示 Memcached 與 Redis 的使用方式。php<?php namespace app\controller; use support\Request; use support\Response; use Memcached; // 引入 Memcached 類 use support\Redis; // 引入 Webman 提供的 Redis Facade class CacheController { /** * 演示 Memcached 的使用方式 * @param Request $request * @return Response */ public function memcached(Request $request): Response { // 連線至 Memcached 伺服器,ServBay 預設在 127.0.0.1:11211 運行 $memcached = new Memcached(); $memcached->addServer('127.0.0.1', 11211); // 設定快取項,有效期 60 秒 $success = $memcached->set('servbay_key', 'Hello Memcached from ServBay!', 60); // 更新 key 和 value if (!$success) { return response('Failed to set Memcached key', 500); } // 取得快取項 $value = $memcached->get('servbay_key'); // 更新 key // 回傳取得的值 return response($value ?: 'Memcached key not found or expired'); // 若未找到則提示 } /** * 演示 Redis 的使用方式 * @param Request $request * @return Response */ public function redis(Request $request): Response { // 使用 Webman 的 Redis Facade 設定快取項 Redis::set('servbay_redis_key', 'Hello Redis from ServBay!'); // 更新 key 和 value // 使用 Webman 的 Redis Facade 取得快取項 $value = Redis::get('servbay_redis_key'); // 更新 key // 回傳取得的值 return response($value ?: 'Redis key not found'); // 若未找到則提示 } }
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
52app/controller/DatabaseController.php
:演示 MySQL 與 PostgreSQL 的資料庫操作。php<?php namespace app\controller; use support\Request; use support\Response; use support\Db; // 引入 Webman 提供的 Db Facade class DatabaseController { /** * 新增使用者至 MySQL 資料庫 * @param Request $request * @return Response */ public function mysqlAdd(Request $request): Response { try { // 使用 Db Facade 連線 'mysql' 資料庫並插入資料 Db::connection('mysql')->table('users')->insert([ 'name' => 'ServBay Webman MySQL User', // 更新範例資料 'email' => 'mysql_demo@servbay.test', // 更新範例信箱 'created_at' => date('Y-m-d H:i:s') // 增加 created_at ]); return response('User added to MySQL'); // 更新回應訊息 } catch (\Exception $e) { return response('Error adding user to MySQL: ' . $e->getMessage(), 500); // 錯誤處理 } } /** * 取得 MySQL 資料庫中的使用者列表 * @param Request $request * @return Response */ public function mysqlGet(Request $request): Response { try { // 使用 Db Facade 連線 'mysql' 資料庫,取得所有使用者 $users = Db::connection('mysql')->table('users')->get(); // 回傳 JSON 格式的使用者列表 return response(json_encode($users), 200, ['Content-Type' => 'application/json']); // 明確 Content-Type } catch (\Exception $e) { return response('Error getting users from MySQL: ' . $e->getMessage(), 500); // 錯誤處理 } } /** * 新增使用者至 PostgreSQL 資料庫 * @param Request $request * @return Response */ public function pgsqlAdd(Request $request): Response { try { // 使用 Db Facade 連線 'pgsql' 資料庫並插入資料 Db::connection('pgsql')->table('users')->insert([ 'name' => 'ServBay Webman PgSQL User', // 更新範例資料 'email' => 'pgsql_demo@servbay.test', // 更新範例信箱 'created_at' => date('Y-m-d H:i:s') // 增加 created_at ]); return response('User added to PostgreSQL'); // 更新回應訊息 } catch (\Exception $e) { return response('Error adding user to PostgreSQL: ' . $e->getMessage(), 500); // 錯誤處理 } } /** * 取得 PostgreSQL 資料庫中的使用者列表 * @param Request $request * @return Response */ public function pgsqlGet(Request $request): Response { try { // 使用 Db Facade 連線 'pgsql' 資料庫,取得所有使用者 $users = Db::connection('pgsql')->table('users')->get(); // 回傳 JSON 格式的使用者列表 return response(json_encode($users), 200, ['Content-Type' => 'application/json']); // 明確 Content-Type } catch (\Exception $e) { return response('Error getting users from PostgreSQL: ' . $e->getMessage(), 500); // 錯誤處理 } } }
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
79
80
81
82
83
84
設定資料庫連線
編輯專案根目錄下的
config/database.php
檔案,設定 MySQL 與 PostgreSQL 的連線資訊。ServBay 預設資料庫主機為127.0.0.1
,端口分別是3306
(MySQL)與5432
(PostgreSQL),root
使用者密碼為password
。php<?php /** * 資料庫設定 */ return [ // 預設使用的資料庫連線 'default' => 'mysql', // 資料庫連線設定列表 'connections' => [ 'mysql' => [ 'driver' => 'mysql', // ServBay 預設的 MySQL 主機與端口 'host' => '127.0.0.1', 'port' => 3306, // 前面建立的資料庫名稱 'database' => 'webman_app', // ServBay 預設的 MySQL 使用者 'username' => 'root', // ServBay 預設的 MySQL 密碼 'password' => 'password', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], 'pgsql' => [ 'driver' => 'pgsql', // ServBay 預設的 PostgreSQL 主機與端口 'host' => '127.0.0.1', 'port' => 5432, // 前面建立的資料庫名稱 'database' => 'webman_app', // ServBay 預設的 PostgreSQL 使用者 'username' => 'root', // ServBay 預設的 PostgreSQL 密碼 'password' => 'password', 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', 'sslmode' => 'prefer', // 可改為 require, verify-ca, verify-full ], // 可在此加入更多資料庫連線... ], ];
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重要提醒: 在正式環境中,務必變更預設資料庫密碼,並避免於程式中硬編碼敏感資訊。
運行 Webman 專案
Webman 專案通常透過其內建的 start.php
腳本啟動 Workerman 行程。這和傳統透過 Nginx/Apache + PHP-FPM 執行方式不同,Webman 屬於常駐記憶體的非同步應用。
於專案根目錄(/Applications/ServBay/www/servbay-webman-app
)下執行下列命令啟動 Webman 專案:
bash
php start.php start
1
執行後若看到 Webman 啟動相關訊息,預設會在 127.0.0.1:8787
監聽 HTTP 請求。
- 注意: 此處的
php
命令即使用 ServBay 環境中的 PHP 執行檔。ServBay 會自動設定你的終端機環境,讓你可直接使用 ServBay 安裝的 PHP 版本。 - 如欲讓 Webman 於背景運行,可使用
-d
參數:php start.php start -d
- 停止 Webman 服務請執行:
php start.php stop
- 重啟 Webman 服務請執行:
php start.php restart
- 平滑重啟(不中斷請求)請執行:
php start.php reload
測試專案功能
Webman 成功啟動並監聽 127.0.0.1:8787
後,可於瀏覽器輸入以下 URL 來測試各項功能:
http://localhost:8787/
:你將看到頁面顯示Hello ServBay & Webman!
。http://localhost:8787/memcached
:頁面顯示Hello Memcached from ServBay!
,代表已成功透過 Webman 連線並使用 ServBay 的 Memcached 服務。http://localhost:8787/redis
:頁面顯示Hello Redis from ServBay!
,代表已成功透過 Webman 連線並使用 ServBay 的 Redis 服務。http://localhost:8787/mysql-add
:頁面顯示User added to MySQL
,將於先前建立的 MySQLusers
資料表插入紀錄。http://localhost:8787/mysql
:頁面會輸出 JSON 格式,包含 MySQLusers
資料表中的使用者列表。http://localhost:8787/pgsql-add
:頁面顯示User added to PostgreSQL
,將於 PostgreSQLusers
資料表插入紀錄。http://localhost:8787/pgsql
:頁面輸出 JSON 格式,包含 PostgreSQLusers
資料表的使用者列表。
如在訪問這些 URL 時遇到問題,請檢查 Webman 終端機輸出是否有錯誤訊息,並確認 ServBay 的 MySQL、PostgreSQL、Redis、Memcached 套件皆在運行且 PHP 擴充已啟用。
常見問題(FAQ)
- Q: 找不到
php start.php start
命令?- A: 請確認已於終端機
cd
進入servbay-webman-app
專案目錄,同時確保 ServBay 安裝的 PHP 已正確加入你的系統 PATH(ServBay 通常會自動處理)。
- A: 請確認已於終端機
- Q: 訪問
localhost:8787
顯示連線失敗?- A: 請檢查終端機運行
php start.php start
的輸出訊息是否有錯誤。確保8787
端口未被其他程式佔用。如已佔用,可修改 Webman 設定檔(例如config/server.php
)選擇其他監聽端口。
- A: 請檢查終端機運行
- Q: 資料庫連線失敗?
- A: 請確認 ServBay 的 MySQL 與 PostgreSQL 套件正在運行。檢查
config/database.php
中的連線資訊(主機、端口、資料庫名稱、使用者、密碼)與 ServBay 設定是否一致(預設使用者為root
,密碼為password
)。也請確認已建立webman_app
資料庫與users
資料表。
- A: 請確認 ServBay 的 MySQL 與 PostgreSQL 套件正在運行。檢查
- Q: Memcached 或 Redis 連線失敗?
- A: 請確認 ServBay 的 Memcached 與 Redis 套件正在運行。檢查
app/controller/CacheController.php
裡的連線地址與端口(預設分別為127.0.0.1:11211
與127.0.0.1:6379
)。確認所用 PHP 版本已啟用memcached
、redis
擴充。
- A: 請確認 ServBay 的 Memcached 與 Redis 套件正在運行。檢查
小結
按照以上步驟,你已成功於 ServBay 本機開發環境中建立、設定並運行基礎的 Webman 專案。你瞭解如何運用 ServBay 提供的一站式服務,快速打造 Webman 的開發環境,並整合資料庫及快取功能。Webman 的高效能特性結合 ServBay 的便利,為你的非同步 PHP 應用開發提供強大支援。希望本指南能協助你更好地運用 ServBay 與 Webman 建立優秀的 Web 應用。