สร้างและเรียกใช้งานโปรเจค Webman ใน ServBay
Webman คืออะไร?
Webman คือเฟรมเวิร์กเว็บ PHP แบบอะซิงโครนัสที่มีประสิทธิภาพสูง สร้างขึ้นบนพื้นฐานของ Workerman และออกแบบมาเพื่อการพัฒนาเว็บแอปพลิเคชันที่ต้องการความพร้อมรับการใช้งานพร้อมกันจำนวนมาก (high concurrency) และประสิทธิภาพที่เหนือกว่า โดยแตกต่างจากเฟรมเวิร์กแบบซิงโครนัสทั่วไป Webman ใช้โมเดลการขับเคลื่อนด้วยอีเวนต์และ I/O แบบไม่บล็อก ทำให้รองรับคำขอหลากหลายได้อย่างมีประสิทธิภาพ นอกจากนี้ยังมี API ที่ใช้งานง่ายและระบบเสริมฟีเจอร์ที่ยืดหยุ่น เหมาะสำหรับการสร้างแอปฯแบบเรียลไทม์, API หรือ microservices
จุดเด่นและข้อได้เปรียบหลักของ Webman
- ประสิทธิภาพสูง: สร้างบน Workerman ใช้ event-driven และ I/O แบบไม่บล็อก รับโหลดพร้อมกันจำนวนมากได้ดีและมี throughputs สูงกว่าเฟรมเวิร์กแบบซิงโครนัส
- ใช้งานง่าย: API ชัดเจนและครบเครื่อง พร้อมฟีเจอร์หลากหลาย นักพัฒนาสามารถเริ่มพัฒนาได้ทันที
- รองรับหลายโปรโตคอล: มีโปรโตคอลระดับแอปฯยอดนิยมในตัว เช่น HTTP, WebSocket ช่วยให้สร้างบริการได้หลายรูปแบบ
- ขยายง่าย: เพิ่มขีดความสามารถผ่านแพ็กเกจ Composer, ปลั๊กอิน หรือ middleware ได้ตามต้องการ
- ใช้ทรัพยากรต่ำ: ดีกว่าการรันเว็บเซิร์ฟเวอร์แบบ PHP-FPM เพราะ Webman รันเป็น process ในหน่วยความจำ resource usage ต่ำกว่า
- มีชุมชนสนับสนุนแข็งแรง: รวมผู้นักพัฒนาที่มีชีวิตชีวาและเอกสารจำนวนมาก
Webman ช่วยให้นักพัฒนาสร้าง Web application และ API ที่มีประสิทธิภาพและ availability สูง เหมาะสำหรับงานที่ต้องรองรับ concurrent requests และ latency ต่ำ
ขั้นตอนสร้างและเรียกใช้งานโปรเจค Webman บน ServBay
คู่มือฉบับนี้จะแนะนำรายละเอียดวิธีสร้างและเรียกใช้งานโปรเจค Webman บน ServBay local development environment พร้อมสาธิตการติดตั้ง Webman, การเขียนโค้ดพื้นฐาน, การเชื่อมต่อฐานข้อมูล (MySQL, PostgreSQL) และแคช (Redis, Memcached)
TIP
ServBay แนะนำให้นักพัฒนาจัดเก็บโปรเจคเว็บไซต์ local ทั้งหมดไว้ที่ไดเรกทอรี /Applications/ServBay/www
เพื่อให้ง่ายต่อการจัดการผ่าน ServBay เช่น การตั้งค่าเว็บไซต์ local (หรือที่เรียกว่า "host")
ความต้องการเบื้องต้น
ก่อนเริ่มต้น ขอให้คุณเตรียมสิ่งต่อไปนี้ให้พร้อม:
- ติดตั้ง ServBay: ต้องติดตั้ง ServBay บน macOS เรียบร้อยแล้ว ServBay จะมีสิ่งจำเป็นสำหรับคู่มือนี้ครบถ้วน เช่น PHP, Composer, MySQL, PostgreSQL, Redis, Memcached ฯลฯ
- เปิดใช้งานแพ็กเกจที่ต้องการ: ผ่านแผงควบคุม ServBay ตรวจสอบให้แน่ใจว่าติดตั้งและรัน Software ต่อไปนี้:
- PHP เวอร์ชั่นที่เลือก (แนะนำ PHP 8.x)
- Composer (มีให้ใน ServBay อยู่แล้ว)
- MySQL
- PostgreSQL
- Redis
- Memcached
- ตรวจสอบว่า PHP เวอร์ชั่นที่ใช้งาน เปิด extensions ที่จำเป็น (
memcached
,redis
,pdo_mysql
,pdo_pgsql
เป็นต้น) ServBay จะเปิด extension ที่ใช้บ่อยให้อยู่แล้ว สามารถตรวจสอบได้ในหน้าตั้งค่า PHP
- เข้าถึง terminal: มีทักษะพื้นฐานในการใช้ terminal บน macOS
ติดตั้ง Webman
ตรวจสอบ Composer ว่าใช้งานได้
ServBay มาพร้อม Composer แล้ว (อ่านเพิ่มเติม) และตั้งค่าให้พร้อมใช้บน terminal รันคำสั่งนี้เพื่อตรวจสอบ:
bashcomposer --version
1หากแสดงเวอร์ชั่น Composer แปลว่าพร้อมใช้งาน
เข้าไดเรคทอรีเว็บไซต์ของ ServBay
เปิด terminal ไปที่ไดเรคทอรี root ที่ ServBay แนะนำสำหรับเว็บไซต์:
bashcd /Applications/ServBay/www
1สร้างโปรเจค Webman ด้วย Composer
ใช้คำสั่ง
create-project
ของ Composer ติดตั้ง Webman ลงโฟลเดอร์ใหม่ ซึ่งเราจะตั้งชื่อโปรเจคว่าservbay-webman-app
:bashcomposer create-project workerman/webman servbay-webman-app
1Composer จะดาวน์โหลด Webman และ dependency หลักๆ จาก Packagist มาไว้ที่
servbay-webman-app
เข้าไปยังโฟลเดอร์โปรเจค
หลังติดตั้งเสร็จ เข้าไปที่โฟลเดอร์โปรเจคใหม่:
bashcd servbay-webman-app
1ติดตั้ง library ที่จำเป็นเพิ่มเติม
เพื่อสาธิตฟังก์ชันฐานข้อมูลและแคช เราจะติดตั้ง Composer package เพิ่มเติม Webman นิยมใช้
illuminate/database
(ของ Laravel),illuminate/redis
ฯลฯ ใช้-W
(--with-dependencies
) เพื่อแก้ dependency conflictbashcomposer require -W illuminate/database illuminate/redis illuminate/pagination illuminate/events symfony/var-dumper
1คำสั่งนี้จะติดตั้ง ORM, Redis client, pagination, event dispatcher และ VarDumper debug tool
สร้างฐานข้อมูลและ table
สำหรับตัวอย่างโค้ดที่จะแสดงผลได้ เราต้องสร้างฐานข้อมูลและตาราง users
ใน MySQL กับ PostgreSQL ของ ServBay โดย username เริ่มต้นคือ root
และรหัสผ่าน password
ใช้ Tools สำหรับจัดการฐานข้อมูลที่มีใน ServBay (เช่น phpMyAdmin หรือ pgAdmin สามารถเข้าผ่าน control panel) หรือใช้ command line เพื่อรัน 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:
สร้าง Table
users
ในฐานข้อมูลwebman_app
- 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:
เขียนโค้ดโปรเจคเว็บ
ขั้นตอนถัดไปคือเพิ่มโค้ดสำหรับกำหนด routing, สร้าง controller และ logic สำหรับเชื่อมต่อกับฐานข้อมูลและแคช
ตั้งค่า Routing
แก้ไขไฟล์
config/route.php
ที่ root ของโปรเจค เพิ่มโค้ดนี้เพื่อนิยาม route ที่ใช้ในตัวอย่าง:php<?php use Webman\Route; use app\controller\IndexController; use app\controller\CacheController; use app\controller\DatabaseController; // กำหนด route ที่ root ไปยัง method index ของ IndexController Route::any('/', [IndexController::class, 'index']); // route สำหรับ cache Route::any('/memcached', [CacheController::class, 'memcached']); Route::any('/redis', [CacheController::class, 'redis']); // route สำหรับ 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']); // เพิ่ม route อื่นๆ ได้ที่นี่...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21สร้างไฟล์ Controller
ที่ไดเรกทอรี
app/controller
ให้สร้างไฟล์IndexController.php
,CacheController.php
และDatabaseController.php
พร้อมเพิ่มโค้ดต่อไปนี้app/controller/IndexController.php
: สำหรับจัดการกับ request ที่ rootphp<?php namespace app\controller; use support\Request; use support\Response; // นำเข้า Response class class IndexController { /** * เมธอดตัวอย่างสำหรับรับ request ที่ root * @param Request $request request object ปัจจุบัน * @return Response ส่งกลับ response object */ public function index(Request $request): Response // ระบุ return type { // ตอบกลับด้วยข้อความง่ายๆ 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 และ Redisphp<?php namespace app\controller; use support\Request; use support\Response; use Memcached; // นำเข้า Memcached class use support\Redis; // นำเข้า Redis Facade ของ Webman class CacheController { /** * สาธิตการใช้ Memcached * @param Request $request * @return Response */ public function memcached(Request $request): Response { // เชื่อมต่อ Memcached server ServBay รันที่ 127.0.0.1:11211 โดยเริ่มต้น $memcached = new Memcached(); $memcached->addServer('127.0.0.1', 11211); // ตั้งค่า cache item อายุ 60 วินาที $success = $memcached->set('servbay_key', 'Hello Memcached from ServBay!', 60); // อัปเดต key และ value if (!$success) { return response('Failed to set Memcached key', 500); } // ดึงค่า cache item $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 { // ใช้ Redis Facade ของ Webman ตั้งค่า cache item Redis::set('servbay_redis_key', 'Hello Redis from ServBay!'); // อัปเดต key และ value // ดึงค่า cache item โดยใช้ 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 และ PostgreSQLphp<?php namespace app\controller; use support\Request; use support\Response; use support\Db; // นำเข้า Webman Db Facade class DatabaseController { /** * เพิ่มผู้ใช้ลง MySQL database * @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', // อัปเดต email '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); // เพิ่ม error handling } } /** * ดึงผู้ใช้ทั้งหมดจาก MySQL * @param Request $request * @return Response */ public function mysqlGet(Request $request): Response { try { // เชื่อมต่อ 'mysql' และดึง user ทั้งหมด $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); // เพิ่ม error handling } } /** * เพิ่มผู้ใช้ลง 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', // อัปเดต email '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); // เพิ่ม error handling } } /** * ดึงผู้ใช้ทั้งหมดจาก PostgreSQL * @param Request $request * @return Response */ public function pgsqlGet(Request $request): Response { try { // เชื่อมต่อ 'pgsql' และดึง user ทั้งหมด $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); // เพิ่ม error handling } } }
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
ที่ root ของโปรเจค กำหนดค่าเชื่อมต่อ MySQL กับ PostgreSQL โดย ServBay จะกำหนด host เป็น127.0.0.1
, port คือ3306
(MySQL) และ5432
(PostgreSQL), username คือroot
และ password คือpassword
php<?php /** * การตั้งค่าฐานข้อมูล */ return [ // connection ที่ใช้โดยเริ่มต้น 'default' => 'mysql', // รายการการตั้งค่าการเชื่อมต่อ 'connections' => [ 'mysql' => [ 'driver' => 'mysql', // Host/Port เริ่มต้นของ MySQL จาก ServBay 'host' => '127.0.0.1', 'port' => 3306, // ฐานข้อมูลที่สร้างไว้แล้ว 'database' => 'webman_app', // ชื่อผู้ใช้ MySQL ที่ ServBay ตั้งไว้โดยเริ่มต้น 'username' => 'root', // รหัสผ่าน MySQL ที่ ServBay ตั้งไว้โดยเริ่มต้น 'password' => 'password', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], 'pgsql' => [ 'driver' => 'pgsql', // Host/Port เริ่มต้นของ PostgreSQL จาก ServBay 'host' => '127.0.0.1', 'port' => 5432, // ฐานข้อมูลที่สร้างไว้แล้ว 'database' => 'webman_app', // ชื่อผู้ใช้ PostgreSQL ที่ ServBay ตั้งไว้โดยเริ่มต้น 'username' => 'root', // รหัสผ่าน PostgreSQL ที่ ServBay ตั้งไว้โดยเริ่มต้น 'password' => 'password', 'charset' => 'utf8', 'prefix' => '', 'schema' => 'public', 'sslmode' => 'prefer', // หรือ require, verify-ca, verify-full ], // เพิ่ม connection ฐานข้อมูลอื่นๆ ได้ที่นี่... ], ];
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หมายเหตุสำคัญ: สำหรับ production อย่าลืมเปลี่ยนรหัสผ่านจากค่าตั้งต้น และหลีกเลี่ยงการเขียนข้อมูลลับในโค้ด
เรียกใช้งานโปรเจค Webman
Webman จะรันผ่านสคริปต์ start.php
ซึ่งจะเป็นการเปิด Workerman process ต่างจาก Apache/Nginx+PHP-FPM เพราะ Webman ทำงานแบบ resident process ในหน่วยความจำ
เข้าไปยัง root ของโปรเจค (/Applications/ServBay/www/servbay-webman-app
) แล้วรันคำสั่งด้านล่างเพื่อเริ่มโปรเจค Webman:
bash
php start.php start
1
เมื่อสั่งรัน จะเห็นคำอธิบายการเริ่มต้น Webman ใน terminal โดยยังรับ HTTP request ที่ 127.0.0.1:8787
เป็นค่า default
- หมายเหตุ: คำสั่ง
php
นี้ใช้ PHP executable ใน ServBay ซึ่ง ServBay จะกำหนดค่า environment ใน terminal ให้พร้อมใช้งานทันที - ถ้าต้องการให้ Webman รันเบื้องหลัง ให้เพิ่ม
-d
เช่นphp start.php start -d
- หยุด Webman ใช้
php start.php stop
- รีสตาร์ท Webman ใช้
php start.php restart
- รีโหลดแบบ smooth (ไม่ interrupt request) ใช้
php start.php reload
ทดสอบฟังก์ชันโปรเจค
หลังจาก Webman เริ่มต้นและรอที่ 127.0.0.1:8787
ให้เข้า browser และทดสอบ URL ดังนี้:
http://localhost:8787/
: จะแสดงข้อความว่าHello ServBay & Webman!
http://localhost:8787/memcached
: จะแสดงข้อความว่าHello Memcached from ServBay!
เป็นการตรวจสอบการเชื่อมต่อ Memcached ผ่าน Webmanhttp://localhost:8787/redis
: จะแสดงข้อความว่าHello Redis from ServBay!
เป็นการตรวจสอบการเชื่อมต่อ Redis ผ่าน Webmanhttp://localhost:8787/mysql-add
: จะแสดงข้อความว่าUser added to MySQL
และเพิ่ม record ใน tableusers
ของ MySQLhttp://localhost:8787/mysql
: จะได้รับ output แบบ JSON ของ user list จาก MySQLhttp://localhost:8787/pgsql-add
: จะแสดงข้อความว่าUser added to PostgreSQL
และเพิ่ม record ใน tableusers
ของ PostgreSQLhttp://localhost:8787/pgsql
: จะได้รับ output แบบ JSON ของ user list จาก PostgreSQL
หากมีปัญหาในการเข้าถึง URL เหล่านี้ กรุณาตรวจสอบ error ใน terminal ที่รัน Webman และดูว่า Service ใน ServBay เช่น MySQL, PostgreSQL, Redis, Memcached รันอยู่ พร้อมเช็ค PHP extension ที่ตั้งไว้
คำถามที่พบบ่อย (FAQ)
- Q: เจอปัญหา
php start.php start
ไม่พบไฟล์?- A: ตรวจสอบว่า cd เข้ามาอยู่ในโฟลเดอร์โปรเจค
servbay-webman-app
แล้ว หรือไม่ ตรวจสอบว่าคุณได้กำหนด PATH ให้กับ PHP ใน ServBay แล้ว (ServBay จะจัดการตรงนี้ให้อัตโนมัติ)
- A: ตรวจสอบว่า cd เข้ามาอยู่ในโฟลเดอร์โปรเจค
- Q: เข้า
localhost:8787
แล้วเชื่อมต่อไม่สำเร็จ?- A: ตรวจสอบ terminal ในขณะรัน
php start.php start
ว่ามี error หรือไม่ ดูว่า port8787
มี process อื่นใช้หรือไม่ (ถ้ามีเปลี่ยนในไฟล์ config เช่นconfig/server.php
)
- A: ตรวจสอบ terminal ในขณะรัน
- Q: เชื่อมต่อฐานข้อมูลไม่ได้?
- A: ตรวจสอบว่า MySQL กับ PostgreSQL ใน ServBay รันอยู่ ดู config ใน
config/database.php
เช่น host, port, database, username, password ว่าเหมือนกับ config ของ ServBay หรือไม่ (default: userroot
, passwordpassword
) พร้อมตรวจสอบว่ามีการสร้าง databasewebman_app
และ tableusers
แล้ว
- A: ตรวจสอบว่า MySQL กับ PostgreSQL ใน ServBay รันอยู่ ดู config ใน
- Q: เชื่อมต่อ Memcached หรือ Redis ไม่ได้?
- A: ตรวจสอบว่า Memcached กับ Redis ใน ServBay รันอยู่ ดูโค้ดใน
app/controller/CacheController.php
ว่าใช้ host/port ถูกต้อง (127.0.0.1:11211
สำหรับ Memcached,127.0.0.1:6379
สำหรับ Redis) พร้อมตรวจสอบว่า PHP สามารถใช้ extensionmemcached
กับredis
ได้
- A: ตรวจสอบว่า Memcached กับ Redis ใน ServBay รันอยู่ ดูโค้ดใน
สรุป
เมื่อทำขั้นตอนข้างต้นเสร็จสิ้น คุณสามารถสร้าง, ตั้งค่า และเรียกใช้งานโปรเจค Webman เบื้องต้นบน ServBay ได้อย่างสมบูรณ์แล้ว คุณจะได้เรียนรู้การใช้ local development environment ที่ครบเครื่องของ ServBay ในการ set up Webman และเชื่อมต่อ database กับ cache Webman ให้ประสิทธิภาพสูง ผสมผสานกับความสะดวกของ ServBay จึงเป็นทางเลือกที่ดีสำหรับการพัฒนา PHP แบบอะซิงโครนัส หวังว่าคู่มือนี้จะช่วยให้คุณใช้งาน ServBay กับ Webman ได้อย่างเต็มประสิทธิภาพสำหรับการสร้าง Web application ที่ยอดเยี่ยม