Tạo và chạy dự án Webman trong ServBay
Webman là gì?
Webman là một framework web PHP bất đồng bộ hiệu năng cao, xây dựng dựa trên Workerman, được thiết kế để phát triển ứng dụng web chịu tải lớn và đáp ứng nhanh. Khác với các framework đồng bộ truyền thống, Webman sử dụng mô hình I/O bất đồng bộ và sự kiện để tối ưu hóa xử lý hàng loạt request đồng thời. Webman sở hữu API trực quan đơn giản và cơ chế mở rộng linh hoạt, lý tưởng cho các ứng dụng thời gian thực, API service, microservice,…
Ưu điểm nổi bật của Webman
- Hiệu năng cao: Dựa trên Workerman, vận hành sự kiện và I/O bất đồng bộ, dễ dàng xử lý lượng kết nối lớn, throughput vượt xa các framework đồng bộ truyền thống.
- Dễ sử dụng: Cung cấp API rõ ràng, tính năng đầy đủ, giúp developer làm quen và phát triển ứng dụng nhanh chóng.
- Hỗ trợ đa giao thức: Tích hợp các giao thức ứng dụng phổ biến như HTTP, WebSocket,… thuận tiện xây dựng nhiều loại service khác nhau.
- Mở rộng linh hoạt: Dễ dàng mở rộng tính năng qua gói Composer, plugins, hay middleware.
- Tiết kiệm tài nguyên: Tối ưu hơn so với mô hình Web server + PHP-FPM truyền thống, ứng dụng luôn chạy trong bộ nhớ nên chi phí tài nguyên thấp.
- Cộng đồng mạnh: Có đông đảo cộng đồng phát triển và tài liệu phong phú.
Webman giúp developer nhanh chóng xây dựng các ứng dụng web, API hiệu năng cao, sẵn sàng cho môi trường đồng thời lớn, độ trễ thấp.
Tạo và vận hành dự án Webman đơn giản với ServBay
Bài hướng dẫn này sẽ chỉ bạn cách xây dựng và chạy một dự án Webman đơn giản trong môi trường phát triển cục bộ ServBay. Chúng ta sẽ cùng thực hiện các bước cài đặt Webman, viết route và controller cơ bản, đồng bộ với các dịch vụ cơ sở dữ liệu (MySQL, PostgreSQL) và bộ nhớ đệm (Redis, Memcached) của ServBay.
TIP
ServBay khuyến nghị bạn lưu trữ tất cả website cục bộ tại thư mục /Applications/ServBay/www
để quản lý tập trung, thuận tiện cấu hình các website.
Chuẩn bị trước khi bắt đầu
Hãy chắc chắn bạn đã chuẩn bị các điều kiện sau:
- Cài đặt ServBay: Bạn đã cài đặt ServBay thành công trên macOS. ServBay cung cấp tất cả phần mềm cần thiết như PHP, Composer, MySQL, PostgreSQL, Redis, Memcached…
- Kích hoạt các package cần thiết: Mở bảng điều khiển ServBay và đảm bảo các package sau đang chạy:
- Phiên bản PHP bạn chọn (nên dùng PHP 8.x trở lên)
- Composer (tích hợp sẵn trong ServBay)
- MySQL
- PostgreSQL
- Redis
- Memcached
- Đảm bảo phiên bản PHP đã bật các extension như
memcached
,redis
,pdo_mysql
,pdo_pgsql
. Thường ServBay đã bật sẵn các extension này, hãy kiểm tra lại trong giao diện cấu hình PHP của ServBay.
- Sử dụng Terminal: Biết cách dùng Terminal trên macOS.
Cài đặt Webman
Xác nhận Composer đã hoạt động
ServBay đã tích hợp Composer và cấu hình để bạn dùng ngay trên Terminal. Chạy lệnh sau để kiểm tra:
bashcomposer --version
1Nếu trả về thông tin phiên bản Composer, bạn đã sẵn sàng.
Truy cập thư mục website của ServBay
Mở Terminal và chuyển vào thư mục gốc website của ServBay:
bashcd /Applications/ServBay/www
1Khởi tạo dự án Webman bằng Composer
Dùng lệnh
create-project
để cài Webman vào thư mục chỉ định và đặt tên project làservbay-webman-app
:bashcomposer create-project workerman/webman servbay-webman-app
1Composer sẽ tải Webman và các dependency vào thư mục mới.
Truy cập thư mục dự án
Khi cài đặt xong, chuyển vào thư mục chứa project:
bashcd servbay-webman-app
1Cài thêm các package cần thiết
Ta sẽ cài một số package để ví dụ sử dụng database và cache:
illuminate/database
(ORM của Laravel),illuminate/redis
… Tham số-W
(--with-dependencies
) giúp cài các dependency tương thích.bashcomposer require -W illuminate/database illuminate/redis illuminate/pagination illuminate/events symfony/var-dumper
1Lệnh trên giúp cài ORM, Redis client, phân trang, event và công cụ debug.
Tạo database và bảng
Để ví dụ hoạt động, hãy tạo database và bảng users
tương ứng trên MySQL và PostgreSQL của ServBay. Mặc định tài khoản root
có mật khẩu là password
.
Bạn có thể dùng các công cụ quản lý của ServBay (phpMyAdmin, pgAdmin, truy cập qua control panel) hoặc dùng lệnh sau.
Tạo database
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:
Tạo bảng
users
trong database- 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; -- Kết nối vào database vừa tạo 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:
Viết mã cho dự án Web
Ta sẽ định nghĩa router, tạo các controller và demo logic tương tác với database, cache.
Cấu hình route
Sửa file
config/route.php
ở thư mục gốc dự án và thêm đoạn sau:php<?php use Webman\Route; use app\controller\IndexController; use app\controller\CacheController; use app\controller\DatabaseController; // Route gốc, map đến phương thức index của IndexController Route::any('/', [IndexController::class, 'index']); // Route demo cache Route::any('/memcached', [CacheController::class, 'memcached']); Route::any('/redis', [CacheController::class, 'redis']); // Route demo database 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']); // Bạn có thể thêm các route khác ở đây...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21Tạo các file controller
Trong thư mục
app/controller
, tạo các file:IndexController.php
,CacheController.php
vàDatabaseController.php
.app/controller/IndexController.php
: Đáp ứng request gốc.php<?php namespace app\controller; use support\Request; use support\Response; // Kết nối class Response class IndexController { /** * Ví dụ xử lý request root * @param Request $request Đối tượng request hiện tại * @return Response Trả về object Response */ public function index(Request $request): Response // Kiểu trả về rõ ràng { // Trả về response dạng text đơn giản return response('Hello ServBay & Webman!'); // Welcome message đã cập nhật } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20app/controller/CacheController.php
: Demo sử dụng Memcached, Redis.php<?php namespace app\controller; use support\Request; use support\Response; use Memcached; // Import lớp Memcached use support\Redis; // Import Redis facade của Webman class CacheController { /** * Demo sử dụng Memcached * @param Request $request * @return Response */ public function memcached(Request $request): Response { // Kết nối server Memcached; mặc định ServBay chạy tại 127.0.0.1:11211 $memcached = new Memcached(); $memcached->addServer('127.0.0.1', 11211); // Đặt giá trị cache, thời hạn 60 giây $success = $memcached->set('servbay_key', 'Hello Memcached from ServBay!', 60); // Key & value đã cập nhật if (!$success) { return response('Failed to set Memcached key', 500); } // Lấy cache item $value = $memcached->get('servbay_key'); // Lấy theo key đã cập nhật // Trả về kết quả nhận được return response($value ?: 'Memcached key not found or expired'); // Thông báo khi không tìm thấy } /** * Demo sử dụng Redis * @param Request $request * @return Response */ public function redis(Request $request): Response { // Đặt giá trị cache qua Redis facade của Webman Redis::set('servbay_redis_key', 'Hello Redis from ServBay!'); // Key & value đã cập nhật // Đọc cache từ Redis $value = Redis::get('servbay_redis_key'); // Lấy theo key đã cập nhật // Trả về kết quả nhận được return response($value ?: 'Redis key not found'); // Thông báo khi không tìm thấy } }
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
: Demo thao tác với MySQL, PostgreSQL.php<?php namespace app\controller; use support\Request; use support\Response; use support\Db; // Import Db facade của Webman class DatabaseController { /** * Thêm user vào database MySQL * @param Request $request * @return Response */ public function mysqlAdd(Request $request): Response { try { // Kết nối 'mysql', chèn dữ liệu Db::connection('mysql')->table('users')->insert([ 'name' => 'ServBay Webman MySQL User', // Data ví dụ 'email' => 'mysql_demo@servbay.test', // Email ví dụ 'created_at' => date('Y-m-d H:i:s') // created_at ]); return response('User added to MySQL'); // Response mới } catch (\Exception $e) { return response('Error adding user to MySQL: ' . $e->getMessage(), 500); // Thông báo lỗi } } /** * Lấy danh sách user từ database MySQL * @param Request $request * @return Response */ public function mysqlGet(Request $request): Response { try { // Kết nối 'mysql', lấy toàn bộ user $users = Db::connection('mysql')->table('users')->get(); // Trả về danh sách dạng JSON return response(json_encode($users), 200, ['Content-Type' => 'application/json']); // Kiểu trả về rõ ràng } catch (\Exception $e) { return response('Error getting users from MySQL: ' . $e->getMessage(), 500); // Thông báo lỗi } } /** * Thêm user vào database PostgreSQL * @param Request $request * @return Response */ public function pgsqlAdd(Request $request): Response { try { // Kết nối 'pgsql', chèn dữ liệu Db::connection('pgsql')->table('users')->insert([ 'name' => 'ServBay Webman PgSQL User', // Data ví dụ 'email' => 'pgsql_demo@servbay.test', // Email ví dụ 'created_at' => date('Y-m-d H:i:s') // created_at ]); return response('User added to PostgreSQL'); // Response mới } catch (\Exception $e) { return response('Error adding user to PostgreSQL: ' . $e->getMessage(), 500); // Thông báo lỗi } } /** * Lấy danh sách user từ database PostgreSQL * @param Request $request * @return Response */ public function pgsqlGet(Request $request): Response { try { // Kết nối 'pgsql', lấy toàn bộ user $users = Db::connection('pgsql')->table('users')->get(); // Trả về danh sách dạng JSON return response(json_encode($users), 200, ['Content-Type' => 'application/json']); // Kiểu trả về rõ ràng } catch (\Exception $e) { return response('Error getting users from PostgreSQL: ' . $e->getMessage(), 500); // Thông báo lỗi } } }
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
Cấu hình kết nối database
Sửa file
config/database.php
ở thư mục gốc, bổ sung thông tin kết nối MySQL và PostgreSQL. Mặc định host là127.0.0.1
, port là3306
(MySQL) và5432
(PostgreSQL), user làroot
, mật khẩu làpassword
.php<?php /** * Cấu hình database */ return [ // Kết nối mặc định sử dụng 'default' => 'mysql', // Danh sách cấu hình các kết nối 'connections' => [ 'mysql' => [ 'driver' => 'mysql', // Host + port mặc định của ServBay 'host' => '127.0.0.1', 'port' => 3306, // Database đã tạo 'database' => 'webman_app', // User mặc định 'username' => 'root', // Mật khẩu mặc định 'password' => 'password', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], 'pgsql' => [ 'driver' => 'pgsql', // Host + port mặc định của ServBay cho PostgreSQL 'host' => '127.0.0.1', 'port' => 5432, // Database đã tạo 'database' => 'webman_app', // User mặc định 'username' => 'root', // Mật khẩu mặc định 'password' => 'password', 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', 'sslmode' => 'prefer', // có thể là require, verify-ca, verify-full ], // Có thể thêm cấu hình database khác tại đây... ], ];
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
46Lưu ý quan trọng: Khi triển khai sản phẩm, hãy đổi mật khẩu database mặc định và tránh hardcode thông tin nhạy cảm trong code.
Chạy dự án Webman
Dự án Webman khởi động tiến trình Workerman thông qua script start.php
đi kèm. Khác với cách chạy qua Nginx/Apache + PHP-FPM truyền thống, Webman là ứng dụng bất đồng bộ luôn trong bộ nhớ.
Tại thư mục dự án (/Applications/ServBay/www/servbay-webman-app
), chạy lệnh sau để khởi động Webman:
bash
php start.php start
1
Sau khi thực thi, thông tin khởi động Webman sẽ hiện lên, ứng dụng mặc định lắng nghe HTTP tại 127.0.0.1:8787
.
- Lưu ý: Lệnh
php
dùng bản PHP trong ServBay. ServBay sẽ giúp bạn tự động cấu hình môi trường Terminal để nhận diện đúng PHP. - Để chạy nền, dùng tham số
-d
:php start.php start -d
. - Muốn dừng Webman, dùng:
php start.php stop
. - Để restart Webman:
php start.php restart
. - Restart mềm (không gián đoạn request):
php start.php reload
.
Kiểm thử dự án
Sau khi Webman lắng nghe tại 127.0.0.1:8787
, bạn có thể truy cập các URL sau trên trình duyệt:
http://localhost:8787/
: Trang sẽ hiển thịHello ServBay & Webman!
.http://localhost:8787/memcached
: Hiển thịHello Memcached from ServBay!
cho biết kết nối Memcached thành công.http://localhost:8787/redis
: Hiển thịHello Redis from ServBay!
nếu kết nối Redis thành công.http://localhost:8787/mysql-add
: Hiển thịUser added to MySQL
, đồng thời tạo bản ghi user vào bảng MySQLusers
.http://localhost:8787/mysql
: Hiển thị danh sách user dạng JSON của MySQL.http://localhost:8787/pgsql-add
: Hiển thịUser added to PostgreSQL
, đồng thời tạo bản ghi user vào bảng PostgreSQLusers
.http://localhost:8787/pgsql
: Hiển thị danh sách user dạng JSON của PostgreSQL.
Nếu gặp lỗi khi truy cập các đường dẫn trên, kiểm tra thông báo trên terminal của Webman, xác nhận các service của ServBay (MySQL, PostgreSQL, Redis, Memcached) đã chạy, và kiểm tra các extension PHP đã bật.
Câu hỏi thường gặp (FAQ)
- Q: Lệnh
php start.php start
báo không tìm thấy file?- A: Đảm bảo bạn đang ở đúng thư mục dự án
servbay-webman-app
trên terminal. Sát sao kiểm tra ServBay đã đưa PHP vào PATH hệ thống (thường tự động cấu hình).
- A: Đảm bảo bạn đang ở đúng thư mục dự án
- Q: Truy cập
localhost:8787
không kết nối được?- A: Xem lại log xuất ra khi chạy
php start.php start
trên terminal. Đảm bảo port8787
không bị ứng dụng khác chiếm dụng; nếu cần, đổi cổng nghe trong file cấu hình Webman (ví dụconfig/server.php
).
- A: Xem lại log xuất ra khi chạy
- Q: Lỗi kết nối database?
- A: Kiểm tra xem các package MySQL và PostgreSQL của ServBay đã hoạt động chưa. Bảo đảm thông tin trong
config/database.php
(host, port, database, username, password) đúng với cấu hình ServBay (root
–password
). Chắc chắn đã tạowebman_app
và bảngusers
.
- A: Kiểm tra xem các package MySQL và PostgreSQL của ServBay đã hoạt động chưa. Bảo đảm thông tin trong
- Q: Lỗi kết nối Memcached hoặc Redis?
- A: Kiểm tra các service Memcached/Redis trong ServBay hoạt động. Đảm bảo
app/controller/CacheController.php
kết nối đúng địa chỉ và cổng (127.0.0.1:11211
và127.0.0.1:6379
). Đảm bảo PHP đã bật các extensionmemcached
vàredis
.
- A: Kiểm tra các service Memcached/Redis trong ServBay hoạt động. Đảm bảo
Tổng kết
Sau các bước trên, bạn đã có thể khởi tạo, cấu hình và vận hành dự án Webman cơ bản trên môi trường phát triển cục bộ ServBay. Những kiến thức ở đây giúp bạn tận dụng dịch vụ tiện ích của ServBay kết hợp sức mạnh của Webman, nhanh chóng xây dựng môi trường phát triển PHP bất đồng bộ với database và cache tích hợp. Sự kết hợp hiệu năng của Webman và tiện lợi của ServBay giúp bạn phát triển ứng dụng web PHP đa nhiệm hiệu quả, hiện đại. Hy vọng bài hướng dẫn này giúp bạn làm chủ ServBay và Webman để xây dựng sản phẩm xuất sắc!