طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 132 · تقنيات تطوير الواجهات الخلفية
الدرس 6 · الوحدة 2: الدوال

خادم Apache والمنافذ وتوجيه الطلبات

كيف يصل الطلب إلى الملف الصحيح؟ وما المنافذ؟ ⏱ نحو 30 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تشرح دور برنامج خادم الويب ومفهوم المنفذ.
  • تحل مشكلة تعارض المنافذ في XAMPP بتغيير إعداد Apache.
  • تتتبع تحويل الرابط إلى ملف، وتقرأ $_SERVER.
  • تبني موجّهًا بسيطًا يرد بالرمز المناسب، وتعرف دور .htaccess.

١ما خادم الويب؟

كلمة «خادم» تُطلق على شيئين: الجهاز نفسه (حاسب يعمل طوال الوقت)، وبرنامج خادم الويب الذي يعمل عليه ويستقبل طلبات HTTP. أشهر برامج خادم الويب:

البرنامجملاحظة
Apacheالأقدم والأكثر انتشارًا مع PHP، وهو الذي في XAMPP. يُضبط بملف httpd.conf وملفات .htaccess.
Nginxسريع وخفيف، شائع في الخوادم الكبيرة. يمرّر طلبات PHP إلى برنامج اسمه PHP-FPM.
LiteSpeedشائع في الاستضافات المشتركة، ويفهم ملفات .htaccess مثل Apache.

دور خادم الويب: يستمع للطلبات، ويحدد الملف المطلوب. فإن كان ملفًّا ثابتًا (صورة، CSS، HTML) أرسله كما هو. وإن كان .php سلّمه لـ PHP، ثم أرسل الناتج.

٢المنافذ: باب لكل خدمة

الجهاز الواحد قد يشغّل خدمات كثيرة: خادم ويب، وقاعدة بيانات، وبريد. فكيف يعرف أي طلب لأي خدمة؟ بـالمنفذ Port: رقم من 0 إلى 65535، وكل خدمة «تستمع» على رقم.

المنفذالخدمة
80HTTP: خادم الويب (الافتراضي، لا يُكتب في الرابط)
443HTTPS: خادم الويب المشفّر
3306MySQL / MariaDB: قاعدة البيانات
8080منفذ بديل شائع للتطوير

الرابط http://localhost/ يعني ضمنيًّا http://localhost:80/. فإن غيّرت منفذ Apache إلى 8080 صار الرابط http://localhost:8080/. والسطر المسؤول في ملف إعداد Apache:

# C:\xampp\apache\conf\httpd.confListen 80ServerName localhost:80DocumentRoot "C:/xampp/htdocs"DirectoryIndex index.php index.html

٣من الرابط إلى الملف

يحوّل Apache مسار الرابط إلى مسار ملف داخل DocumentRoot:

الرابطالملف على القرص
http://localhost/htdocs/index.php (الملف الافتراضي من DirectoryIndex)
http://localhost/132/hello.phphtdocs/132/hello.php
http://localhost/img/logo.pnghtdocs/img/logo.png يُرسل كما هو
http://localhost/nothing.phpلا يوجد ← 404 Not Found

ويعطيك PHP معلومات الطلب والخادم في المصفوفة $_SERVER:

<?php$keys = ['REQUEST_METHOD', 'REQUEST_URI', 'SCRIPT_NAME', 'QUERY_STRING', 'HTTP_HOST', 'SERVER_PORT'];foreach ($keys as $k) {    echo str_pad($k, 15) . " = " . ($_SERVER[$k] ?? '') . "\n";}

٤الموجّه: ملف واحد لكل الصفحات

بدل أن يكون لكل صفحة ملف منفصل يكرر القائمة والتذييل، نستخدم موجّهًا Router: ملف واحد يستقبل كل الطلبات، ويقرر ماذا يعرض حسب الطلب. هذا أساس كل أطر العمل الحديثة (Laravel وغيرها). وإن لم يجد الصفحة رد بالرمز 404 عبر http_response_code():

<?php// index.php: موجّه واحد لكل صفحات الموقع$page = $_GET['page'] ?? 'home'; $pages = [    'home'    => ['الرئيسية', 'مرحبًا بك في متجر الواحة.'],    'about'   => ['من نحن', 'متجر سعودي للقهوة والتمور منذ 2020.'],    'contact' => ['تواصل معنا', 'واتساب: 0550000000'],]; if (!isset($pages[$page])) {    http_response_code(404);    $title = 'غير موجودة';    $body = 'الصفحة المطلوبة غير موجودة.';} else {    [$title, $body] = $pages[$page];}?><nav>  <a href="?page=home">الرئيسية</a> |  <a href="?page=about">من نحن</a> |  <a href="?page=contact">تواصل</a></nav><h1><?= $title ?></h1><p><?= $body ?></p>
🧪 مختبر الخادماضغط ▶ تشغيل، ثم تنقّل بالروابط داخل المتصفح المصغّر. جرّب إضافة صفحة رابعة إلى المصفوفة.

٥روابط أجمل: ‎.htaccess‎ وإعادة الكتابة

الرابط /index.php?page=about يعمل، لكن /about أجمل وأسهل للحفظ ولمحركات البحث. في Apache يحوّل الملف .htaccess (يوضع في مجلد الموقع) الرابط الجميل إلى الموجّه داخليًّا، دون أن يرى المستخدم ذلك:

# .htaccessRewriteEngine On# إن لم يكن الطلب ملفًّا أو مجلدًا موجودًا فعلًا…RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-d# …فأرسله إلى index.php مع المسارRewriteRule ^(.*)$ index.php?page=$1 [QSA,L]

وبهذا يصل الطلب GET /about إلى index.php وفيه $_GET['page'] = 'about'. يحتاج ذلك تفعيل الوحدة mod_rewrite (مفعّلة في XAMPP افتراضيًّا).

٦الملفات التي لا يجب أن تُطلب

كل ملف داخل htdocs يمكن نظريًّا طلبه من الرابط. لذلك:

# منع الوصول إلى ملفات الإعداد والنسخ الاحتياطية<FilesMatch "\.(env|ini|log|bak|sql)$">    Require all denied</FilesMatch>Options -Indexes

توقّع وتحقّق

المنفذ الافتراضي لـ HTTP هو:

ولذلك لا نكتبه في الرابط.

Apache يشغّل على المنفذ 8080. الرابط الصحيح:

المنفذ بعد نقطتين.

أي سطر يجعل الرد برمز 404؟

يضبط رمز الحالة في الاستجابة.

ما فائدة ملف .htaccess في المثال؟

RewriteRule.

الخلاصة

تحدٍّ برمجي: موجّه لموقع الكلية

متوسط

اكتب موجّهًا في index.php لموقع قسم البرمجة. يعرض الصفحة حسب المعامل page، ويرد بـ 404 للصفحات غير الموجودة.

المطلوب:
  • الصفحات: home وعنوانها «قسم البرمجة»، و courses وعنوانها «المقررات»، و staff وعنوانها «المدربون».
  • اعرض العنوان في <h1>. إن لم يُرسل page فاعرض home.
  • لصفحة غير موجودة: رمز الحالة 404 و <h1>404 - الصفحة غير موجودة</h1>.
👀 اعرض الاستجابة المطلوبة
✓ التحقق الآلي: يرسل المختبر هذه الطلبات إلى خادمك بالترتيب ثم يفحص الاستجابات
  1. GET /index.php
  2. GET /index.php?page=courses
  3. GET /index.php?page=staff
  4. GET /index.php?page=jobs
  • الكود يعمل بلا أخطاء أو تحذيرات
  • بلا page ← قسم البرمجة
  • page=courses ← المقررات
  • page=staff ← المدربون
  • page=jobs ← رمز الحالة 404
  • page=jobs ← رسالة 404
  • الصفحات الموجودة برمز 200

💡 تلميح 1
خزّن العناوين في مصفوفة ترابطية مفاتيحها أسماء الصفحات، ثم افحص isset($titles[$page]).
💡 تلميح 2
لا تنسَ ?? حتى لا يظهر تحذير حين لا يُرسل page.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

<?php$page = $_GET['page'] ?? 'home';$titles = [    'home' => 'قسم البرمجة',    'courses' => 'المقررات',    'staff' => 'المدربون',];if (isset($titles[$page])) {    echo "<h1>{$titles[$page]}</h1>";} else {    http_response_code(404);    echo "<h1>404 - الصفحة غير موجودة</h1>";}
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس