إنشاء وتشغيل مشروع Webman في ServBay
ما هو Webman؟
Webman هو إطار عمل ويب PHP غير متزامن عالي الأداء ومبني على Workerman، صُمم خصيصًا لبناء تطبيقات ويب عالية التوازي والأداء. على عكس الأطر التقليدية المتزامنة والمعطلة، يعتمد Webman على نموذج الإدخال/الإخراج الحدثي وغير المتزامن، مما يجعله متفوقًا في معالجة عدد كبير من الطلبات المتزامنة. يقدم Webman واجهات برمجة تطبيقات بسيطة وسهلة الاستخدام وآلية توسعة مرنة، لذلك هو مثالي لبناء تطبيقات الوقت الفعلي، وخدمات API، والخدمات المصغرة وغير ذلك.
المزايا والخصائص الرئيسية لإطار Webman
- أداء عالي: مبني على Workerman، ويستفيد من نموذج الأحداث وI/O غير المعطل، ما يجعله قادرًا على معالجة آلاف الاتصالات المتزامنة مع معدل إنتاجية يفوق الأطر التقليدية.
- سهولة الاستخدام: واجهات وخدمات API بسيطة وغنية تسهّل على المطورين بدء العمل بسرعة وبناء التطبيقات بسهولة.
- دعم متعدد البروتوكولات: يدعم بروتوكولات HTTP وWebSocket والمزيد من بروتوكولات طبقة التطبيقات الشائعة، ما يسمح ببناء أنواع مختلفة من الخدمات.
- توسعة مرنة: يدعم توسيع وظائف الإطار بسهولة عبر حِزمات Composer والإضافات وMiddlewares.
- استخدام منخفض للموارد: بالمقارنة مع وضع خادم الويب التقليدي + PHP-FPM، يعمل Webman كتطبيق مقيم بالذاكرة مع استهلاك أقل للموارد.
- دعم مجتمعي قوي: مجتمع مطورين نشط وموارد توثيقية غنية.
يساعد Webman المطورين على بناء تطبيقات ويب وخدمات API عالية الأداء والاعتمادية، خاصة في الحالات التي تتطلب معالجة متزامنة عالية وزمن استجابة منخفض.
إنشاء وتشغيل مشروع Webman بسيط باستخدام ServBay
يشرح هذا الدليل كيفية استخدام Webman لإنشاء وتشغيل مشروع ويب بسيط في بيئة تطوير ServBay المحلية. سنوضح كيفية تثبيت Webman، وكتابة الشيفرة الأساسية للراوتينج والتحكم، وكيفية ربط قواعد بيانات ServBay (MySQL, PostgreSQL) وخدمات التخزين المؤقت (Redis, Memcached).
TIP
توصي ServBay المطورين بحفظ جميع مشاريع مواقعهم المحلية في دليل /Applications/ServBay/www
لتسهيل إدارة ServBay وتكوين المواقع المحلية (كانت تُسمى سابقًا "المضيفين").
المتطلبات المسبقة
قبل البدء، تأكد من إنجاز ما يلي:
- تثبيت ServBay: يجب أن تكون قد قمت بتثبيت ServBay بنجاح على نظام macOS. توفر 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
. عادةً يتم تفعيل هذه الامتدادات بشكل افتراضي في ServBay ويمكنك مراجعتها من إعدادات PHP في لوحة تحكم ServBay.
- الوصول إلى الطرفية (Terminal): معرفة أساسية بكيفية استخدام تطبيق الطرفية في macOS.
تثبيت Webman
تأكد من توفر Composer
يأتي ServBay مدمجًا مع Composer ويمكن استخدامه مباشرة من الطرفية. لتأكيد التوفر، نفذ الأمر التالي:
bashcomposer --version
1إذا ظهرت لك معلومات إصدار Composer فهذا يعني أن Composer جاهز للاستخدام.
الدخول إلى مجلد مواقع ServBay
من الطرفية، انتقل إلى المجلد المقترح لجذر المواقع في ServBay:
bashcd /Applications/ServBay/www
1إنشاء مشروع Webman بواسطة Composer
استخدم أمر
create-project
في Composer لتثبيت إطار Webman في مجلد محدد. سنسمّي المشروعservbay-webman-app
:bashcomposer create-project workerman/webman servbay-webman-app
1سيتم تنزيل 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، ووحدة التصفح، وجدولة الأحداث، وأدوات Debugging متقدمة VarDumper.
إنشاء قاعدة بيانات وجداول
لكي تعمل الشيفرة التوضيحية بشكل صحيح، يجب أن ننشئ قاعدة بيانات وجداول users
في كل من MySQL وPostgreSQL في ServBay. كلمة مرور مستخدم root
الافتراضية في ServBay هي password
.
يمكنك استخدام أدوات إدارة قواعد البيانات المقدمة من ServBay (مثل phpMyAdmin أو pgAdmin، عبر لوحة التحكم)، أو تنفيذ الأوامر التالية من الطرفية مباشرة.
إنشاء قاعدة بيانات باسم
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:
إنشاء جدول
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:
كتابة شيفرة المشروع
الآن سنضيف الشيفرات اللازمة لتعريف المسارات وإنشاء المراقبين (Controllers) وتنفيذ منطق التعامل مع قواعد البيانات والتخزين المؤقت.
إعداد المسارات (Routes)
عدّل ملف
config/route.php
في جذر المشروع لإضافة المسارات التالية:php<?php use Webman\Route; use app\controller\IndexController; use app\controller\CacheController; use app\controller\DatabaseController; // تعريف المسار الجذري وربطه بوظيفة index في IndexController 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إنشاء ملفات المراقب (Controllers)
في مجلد
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 إرجاع كائن الاستجابة */ 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; // استيراد Redis Facade المقدم من Webman 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); // تحديث المفتاح والقيمة if (!$success) { return response('Failed to set Memcached key', 500); } // جلب العنصر من التخزين المؤقت $value = $memcached->get('servbay_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 لتعيين قيمة مؤقتة Redis::set('servbay_redis_key', 'Hello Redis from ServBay!'); // المفتاح والقيمة المحدثة // جلب القيمة $value = Redis::get('servbay_redis_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; // استيراد Db Facade المقدم من Webman 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' => '[email protected]', // مثال بريد إلكتروني 'created_at' => date('Y-m-d H:i:s') // تعيين وقت الإنشاء ]); 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 { // جلب جميع المستخدمين من قاعدة بيانات 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' => '[email protected]', // مثال بريد إلكتروني 'created_at' => date('Y-m-d H:i:s') // تعيين وقت الإنشاء ]); 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 { // جلب جميع المستخدمين من قاعدة بيانات PostgreSQL $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', // مضيف و منفذ 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', // مضيف و منفذ 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 ], // يمكنك إضافة المزيد من الاتصالات هنا ... ], ];
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 كتطبيق PHP غير متزامن مقيم بالذاكرة.
لتشغيل المشروع، وفي المجلد الجذر (/Applications/ServBay/www/servbay-webman-app
) نفذ الأمر التالي:
bash
php start.php start
1
بعد تنفيذ الأمر ستظهر لك معلومات التشغيل. افتراضيًا، سيستمع التطبيق على 127.0.0.1:8787
لطلبات HTTP.
- ملاحظة: أمر
php
هنا هو إصدار PHP المُثبت والمُدار عبر 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
، يمكنك زيارة الروابط التالية عبر المتصفح لاختبار كل وظيفة:
http://localhost:8787/
سترى عبارةHello ServBay & Webman!
.http://localhost:8787/memcached
سترى عبارةHello Memcached from ServBay!
، مما يعني نجاح الاتصال بخدمة Memcached في ServBay.http://localhost:8787/redis
سترى عبارةHello Redis from ServBay!
، مما يعني نجاح الاتصال بخدمة Redis في ServBay.http://localhost:8787/mysql-add
سترى عبارةUser added to MySQL
، وستتم إضافة سجل جديد في جدولusers
بقاعدة بيانات MySQL.http://localhost:8787/mysql
سترى قائمة مستخدمين بصيغة JSON من جدولusers
في MySQL.http://localhost:8787/pgsql-add
سترى عبارةUser added to PostgreSQL
، وستتم إضافة سجل جديد في جدولusers
في قاعدة بيانات PostgreSQL.http://localhost:8787/pgsql
سترى قائمة مستخدمين بصيغة JSON من جدولusers
في PostgreSQL.
إذا واجهت مشاكل في أي من الروابط أعلاه، رجاءً تحقق من رسائل الخطأ في الطرفية وتأكد من تشغيل حزم MySQL, PostgreSQL, Redis, Memcached في ServBay وأن جميع الإمتدادات الضرورية لـ PHP مُفعلة.
الأسئلة الشائعة (FAQ)
- س: أمر
php start.php start
غير موجود؟- ج: تأكد من أنك نفذت أمر
cd
لتدخل إلى مجلد مشروعservbay-webman-app
. تحقق أيضًا من إضافة PHP الخاص بـ ServBay إلى متغير PATH في نظامك (يقوم ServBay بذلك تلقائيًا عادةً).
- ج: تأكد من أنك نفذت أمر
- س: ظهور رسالة تعذر الاتصال عند زيارة
localhost:8787
؟- ج: راجع رسائل الطرفية الناتجة عن تشغيل
php start.php start
للبحث عن الأخطاء. تأكد من أن المنفذ8787
غير مستخدم بواسطة برنامج آخر، ويمكنك تعديله في ملف الإعدادات (config/server.php
) إذا احتجت.
- ج: راجع رسائل الطرفية الناتجة عن تشغيل
- س: فشل في الاتصال بقاعدة البيانات؟
- ج: تحقق من أن حزم MySQL وPostgreSQL تعمل في ServBay. تحقق من بيانات الاتصال الموجودة في
config/database.php
(المضيف، المنفذ، قاعدة البيانات، المستخدم، كلمة المرور) وأنها مطابقة لإعدادات ServBay الافتراضية (root
/password
). وتأكد من إنشاء قاعدة البياناتwebman_app
وجدولusers
.
- ج: تحقق من أن حزم MySQL وPostgreSQL تعمل في ServBay. تحقق من بيانات الاتصال الموجودة في
- س: فشل الاتصال بـ Memcached أو Redis؟
- ج: تأكد من عمل حزم Memcached وRedis في ServBay، وافحص عناوين ومنافذ الاتصال في
app/controller/CacheController.php
(افتراضيًا127.0.0.1:11211
و127.0.0.1:6379
). تأكد كذلك من تفعيل امتداداتmemcached
وredis
في إصدار PHP المستخدم.
- ج: تأكد من عمل حزم Memcached وRedis في ServBay، وافحص عناوين ومنافذ الاتصال في
الملخص
باتباع الخطوات السابقة تكون قد أنشأت، وهيأت، وشغلت مشروع Webman أساسي في بيئة تطوير ServBay المحلية بنجاح. تعلمت كيف تستفيد من خدمات ServBay المتكاملة لإعداد بيئة تطوير Webman بسرعة، ودمج قواعد البيانات وخدمات التخزين المؤقت بسهولة. يمزج Webman أداءه العالي مع مرونة ServBay ليقدّم دعمًا قويًا لتطوير تطبيقات PHP غير المتزامنة. نأمل أن يساعدك هذا الدليل على الاستفادة القصوى من ServBay وWebman في بناء تطبيقات ويب متميزة.