URL الكامل في PHP: كيفية الحصول عليه بسرعة وبدون أخطاء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

كيف تحصل على URL الكامل في PHP دون أن تصاب بالجنون؟

\n\n

كل مطور PHP واجه مرة واحدة على الأقل مهمة: "كيف أحصل على URL الكامل للصفحة الحالية؟". قد يبدو الأمر بسيطًا — خذ $_SERVER['HTTP_HOST']، أضف $_SERVER['REQUEST_URI'] — وانتهى الأمر. لكن الواقع، كالعادة، يفرض تعديلاته. HTTP أم HTTPS؟ وماذا لو كان المنفذ غير قياسي؟ وماذا لو كان الموقع خادم وكيل؟ وماذا لو لم يكن المطلوب مجرد الحصول عليه، بل القيام بذلك بسرعة، دون تسرب للذاكرة، وباحتياطي للمستقبل؟

\n\n

سؤال "Get the full URL in PHP" على Stack Overflow حصد آلاف المشاهدات وعشرات الإجابات. هذا ليس من قبيل الصدفة: الموضوع يبدو بسيطًا، لكن المخاطر الخفية فيه كثيرة. اليوم سنشرح ليس فقط "كيف تفعل"، بل كيف تفعل ذلك بشكل صحيح وسريع وموثوق. هيا بنا!

\n\n

لماذا النسخ البسيط من $_SERVER هو أمر سيء؟

\n\n

غالبًا ما يكتب المطورون المبتدئون بهذا الشكل:

\n\n
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
\n\n

للوهلة الأولى — يعمل. لكن دعنا نلقي نظرة على المشاكل:

\n
    \n
  • لا يوجد HTTPS. إذا كان الموقع يعمل عبر HTTPS، ستحصل على http:// — وسيبدأ المتصفح في الشكوى من المحتوى المختلط.
  • \n
  • المنفذ. إذا كان المنفذ غير قياسي (مثل 8080)، فسيتم فقدانه إذا لم تستخدم $_SERVER['SERVER_PORT'].
  • \n
  • الخوادم الوكيلة وموازنات التحميل. خلف الوكيل العكسي (Nginx, Cloudflare)، قد لا يكون $_SERVER['HTTP_HOST'] هو ما يراه المستخدم.
  • \n
  • الأمان. يمكن للمهاجم تزوير قيمة HTTP_HOST (حقن رأس المضيف).
  • \n
\n\n

باختصار، النسخ واللصق من أول إجابة على Stack Overflow ليس الخيار الأفضل. دعنا نكتب دالة صحيحة وعالية الأداء.

\n\n

الدالة المثالية: الحصول على URL الكامل بشكل صحيح

\n\n

إليك دالة موثوقة تراعي جميع السيناريوهات الأساسية:

\n\n
function getFullUrl(): string {\n    $protocol = 'http';\n    if (\n        (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')\n        || (int)$_SERVER['SERVER_PORT'] === 443\n    ) {\n        $protocol = 'https';\n    }\n\n    // مراعاة الرؤوس من الوكيل (إذا كنا نثق به)\n    $host = $_SERVER['HTTP_HOST'] ?? '';\n    if (empty($host) && !empty($_SERVER['SERVER_NAME'])) {\n        $host = $_SERVER['SERVER_NAME'];\n    }\n\n    // التحقق من المنفذ\n    $port = (int)$_SERVER['SERVER_PORT'];\n    $portSuffix = '';\n    if (\n        ($protocol === 'http' && $port !== 80)\n        || ($protocol === 'https' && $port !== 443)\n    ) {\n        $portSuffix = ':' . $port;\n    }\n\n    $uri = $_SERVER['REQUEST_URI'] ?? '/';\n\n    return $protocol . '://' . $host . $portSuffix . $uri;\n}
\n\n

ما المهم هنا؟

\n
    \n
  • نتحقق من HTTPS — الطريقة القياسية، تعمل في 99% من الحالات.
  • \n
  • نأخذ في الاعتبار SERVER_PORT — إذا كان الموقع على منفذ غير قياسي، لا نفقده.
  • \n
  • خيار احتياطي عبر SERVER_NAME — في حال كان HTTP_HOST فارغًا.
  • \n
  • لا نستخدم $_SERVER['SCRIPT_URI'] — فهو غير موجود في كل مكان.
  • \n
\n\n

تحسين الأداء: عندما تكون كل ميلي ثانية مهمة

\n\n

إذا كنت تستدعي هذه الدالة في كل صفحة أو في حلقة، يجب التفكير في السرعة. إليك بعض الحيل:

\n\n

1. تخزين النتيجة مؤقتًا

\n

إذا كان URL لا يتغير ضمن طلب واحد (وهو لا يتغير)، قم بتخزينه مؤقتًا:

\n\n
function getFullUrlCached(): string {\n    static $url = null;\n    if ($url === null) {\n        $url = getFullUrl(); // نستخدم الدالة أعلاه\n    }\n    return $url;\n}
\n\n

المتغير الثابت يحتفظ بالقيمة بعد الاستدعاء الأول — لا حسابات متكررة.

\n\n

2. تجنب العمليات الزائدة

\n

لا تستخدم filt

المدونات

توصيات الكتب