⏱️ جاري الحساب…

متغيرات الاستعلام في ووردبريس: تسجيل Query Vars والتحقق من القيم

رسم مفاهيمي يوضح متغيرات الاستعلام في ووردبريس ضمن سلسلة تطوير ووردبريس
📋 فهرس محتويات المقال (اضغط للتنقل السريع) ▾

هذا المقال رقم 10 من 100 في سلسلة معمارية ووردبريس من الأساسيات إلى المشروع النهائي، ضمن المستوى 2: التوجيه ونظام الروابط (Routing & Rewrite).

يا مرحب يا هندسة! لو ووردبريس ده كان محكمة قانونية، فـ متغيرات الاستعلام (Query Variables – Query Vars) هي الأدلة الرسمية الوحيدة المعترف بها والمقبولة لدخول قاعة المحاكمة! الكثير من المطورين لما يحب يمرر قيمة في الرابط (مثل: تصفية المنتجات حسب السعر، أو رقم صفحة، أو كود خصم)، بيستسهل ويكتب مباشرة في كوده: $my_var = $_GET['my_var'];. هذه الطريقة ليست فقط غير معمارية وتخالف معايير ووردبريس القياسية، بل إنها تفتح أبواباً واسعة للثغرات الأمنية، وتتجاهل كلياً نظام الروابط الدائمة (Pretty Permalinks)، وتمنع الاستفادة من قوة كائن WP_Query ونظام التخزين المؤقت (Object Cache)!

في هذا الدليل المعماري الموسع، هنشرح بالعامية المصرية التقنية كل ما يخص Query Vars في نواة ووردبريس؛ هنفهم الفلسفة المعمارية وراء وجودها، ونتعرف على كتالوج المتغيرات المحجوزة للنواة، وكيفية تسجيل المتغيرات المخصصة عبر فلتر query_vars، والتحقق الصارم وتطهير القيم لمنع هجمات XSS والحقن البرمجي، مع تطبيق عملي متكامل لبناء محرك تصفية دورات متقدم، ودراسة حالة حقيقية لمتجر يضم 50,000 منتج، وبنك أسئلة شائعة شامل ومصادر رسمية موثقة.

1. الفلسفة المعمارية لمتغيرات الاستعلام: لماذا تمنع النواة القراءة المباشرة من $_GET؟

في PHP التقليدية، أي معامل يتم تمريره في نهاية الرابط بعد علامة الاستفهام ?key=value يذهب مباشرة للمتغير العام $_GET. لماذا إذن صممت نواة ووردبريس نظاماً وسيطاً كاملاً اسمه Query Variables؟

  1. التجريد والتوحيد (Abstraction & Decoupling): ووردبريس يريد فصل “طريقة طلب الرابط” عن “البيانات المطلوبة”. الزائر قد يطلب المقال برابط قبيح: /?p=15 أو برابط جميل وأنيق: /articles/wordpress-hooks/. بفضل كلاس WP_Rewrite وparse_request، يتم تحويل كلا الرابطين المختلفين تماماً في الشكل إلى نفس مصفوفة الـ Query Vars الموحدة! كود القالب وكائن WP_Query يتعاملان مع متغير نقي وموحد دون الاهتمام بكيف كتب الزائر الرابط في المتصفح!
  2. الحماية والأمان الصارم (Security Whitelisting): مصفوفة $_GET مفتوحة لأي نص عشوائي أو كود خبيث يمرره المهاجم. أما مصفوفة query_vars فتعمل بنظام القائمة البيضاء (Whitelist)؛ أي معامل غير مسجل مسبقاً في النواة أو لم تقم إضافتك بتسجيله صراحة يتم إسقاطه وحذفه فوراً قبل أن يلمس قاعدة بيانات الموقع.
  3. التوافق مع بيئة التخزين المؤقت (Object Cache & Transients): كائن WP_Query يقوم بتوليد بصمة هاش فريدة (Query Hash) بناءً على مصفوفة query_vars لتخزين نتائج الاستعلام في Redis أو Memcached، وهو ما يستحيل تحقيقه بدقة إذا اعتمد المطورون على متغيرات $_GET العشوائية.

2. الفهرس الشامل لمتغيرات الاستعلام الأساسية في نواة ووردبريس

تحتفظ النواة بقائمة طويلة من المتغيرات العامة المحجوزة مسبقاً داخل كلاس WP. إليك تصنيف المتغيرات الأساسية الأكثر استخداماً وتأثيرها على استعلام قاعدة البيانات:

متغير الاستعلام (Query Var)نوع البيانات المتوقعالهدف والتأثير على الاستعلام
pIntegerجلب منشور محدد بواسطة رقم المعرف الخاص به (Post ID)
nameStringجلب منشور فردي بواسطة اسمه اللطيف (Post Slug)
pagenameStringجلب صفحة ثابتة فردية بواسطة مسارها (Page Slug)
post_typeString / Arrayتحديد نوع المنشور المستهدف (مثل: post, page, az_course)
cat أو category_nameInteger / Stringتصفية المنشورات التابعة لمعرف تصنيف معين أو اسمه اللطيف
tag أو tag_idString / Integerتصفية المنشورات التابعة لوسم محدد (Tag Slug / ID)
sStringتشغيل محرك البحث النصي في جدول wp_posts بالكلمات الدلالية الممررة
pagedIntegerرقم الصفحة الحالية في نتائج الترقيم (Pagination)
author_nameStringعرض أرشيف المقالات الخاصة بكاتب معين بواسطة اسمه اللطيف
feedStringتوليد خلاصات الأخبار (RSS, Atom, RDF) للمحتوى المطلوب

⚠️ تحذير معماري في غاية الخطورة: لا تستخدم الأسماء المحجوزة لمتغيراتك الخاصة!

لو قمت بتسمية متغير خاص بك في الرابط باسم محجوز للنواة، مثل كتابة: ?name=mohamed لتمرير اسم الطالب، سيقوم ووردبريس بتفسير كلمة name على أنها اسم مقال في قاعدة البيانات! وسيقوم بالبحث عن مقال رابطه mohamed؛ ولن يجده، فيتحول موقعك فوراً لصفحة 404 Not Found! استخدم دائماً بادئة فريدة لمتغيراتك المخصصة مثل: az_student_name.

3. التسجيل المعماري للمتغيرات المخصصة عبر فلتر query_vars

إذا أردت لووردبريس أن يعترف بمتغير مخصص جديد في الرابط، يجب تسجيله في القائمة البيضاء للنواة عبر فلتر query_vars. إليك الطريقة المعيارية المعتمدة:

// تسجيل متغيرات الاستعلام المخصصة لدبلومة ووردبريس
add_filter( 'query_vars', 'az_register_platform_query_vars' );

function az_register_platform_query_vars( array $vars ): array {
    // إضافة المتغيرات المخصصة لمصفوفة القائمة البيضاء للنواة
    $custom_vars = [
        'az_level',       // مستوى الدورة (مبتدئ / متوسط / متقدم)
        'az_track',       // التخصص (فرونت إند / ووردبريس / شوبيفاي)
        'az_price_range', // النطاق السعري
        'az_sort',        // ترتيب النتائج (الأحدث / الأعلى تقييماً)
        'az_cert_id',     // رقم التحقق من الشهادة
    ];

    return array_merge( $vars, $custom_vars );
}

بمجرد تسجيل هذه المتغيرات، سيتعرف عليها ووردبريس تلقائياً سواء جاءت عبر روابط الـ GET التقليدية مثل ?az_level=advanced، أو جاءت مستخرجة من الروابط الدائمة المنمقة عبر كلاس WP_Rewrite مثل /courses/level/advanced/!

4. القراءة والتحقق الصارم وتطهير القيم (Sanitization & Validation)

بعد تسجيل المتغير، كيف نقرأه بأمان داخل القالب أو الإضافة؟

النواة توفر دالتين مركزيتين للتعامل مع هذه المتغيرات:

  • get_query_var( string $var, mixed $default = '' ): قراءة قيمة المتغير المعتمد، مع إمكانية تحديد قيمة افتراضية في حال لم يتم تمرير المتغير.
  • set_query_var( string $var, mixed $value ): تعديل أو فرض قيمة متغير برمجياً قبل بدء استعلام WP_Query.

قاعدة التطهير الصارمة (Strict Sanitization): لا تثق أبداً في القيمة المسترجعة حتى لو كانت قادمة من get_query_var! يجب دائماً تنقيتها والتأكد من مطابقتها لنوع البيانات المتوقع:

// 1. قراءة وتطهير رقم الصفحة (Integer)
$current_page = absint( get_query_var( 'paged', 1 ) );
if ( $current_page < 1 ) {
    $current_page = 1;
}

// 2. قراءة وتطهير متغير نصي باستخدام قائمة بيضاء محددة (Enum Validation)
$raw_level = sanitize_key( get_query_var( 'az_level' ) );
$allowed_levels = [ 'beginner', 'intermediate', 'advanced' ];

// إذا كانت القيمة غير مسموح بها، نلغيها فوراً!
$safe_level = in_array( $raw_level, $allowed_levels, true ) ? $raw_level : '';

// 3. قراءة كود تحقق مكون من حروف وأرقام فقط عبر Regex
$raw_cert = get_query_var( 'az_cert_id' );
$safe_cert = preg_match( '/^[A-Z0-9-]{8,20}$/', $raw_cert ) ? sanitize_text_field( $raw_cert ) : '';

5. تطبيق عملي: بناء محرك تصفية دورات متقدم (Course Filter Engine)

تعال نبني معمارية حقيقية متكاملة لمحرك تصفية دورات في منصة تدريبية؛ يعتمد على Query Vars لتحديد الشروط، ويستخدم خطاف pre_get_posts لتعديل استعلام قاعدة البيانات الرئيسي تلقائياً وبأقصى سرعة ممكنة:

/**
 * محرك تصفية دورات دبلومة ووردبريس المعماري
 * دمج Query Vars مع الاستعلام الرئيسي عبر pre_get_posts
 */

// 1. تسجيل متغيرات التصفية في النواة
add_filter( 'query_vars', function( array $vars ): array {
    $vars[] = 'course_level';
    $vars[] = 'course_price_max';
    return $vars;
});

// 2. تطبيق شروط التصفية على الاستعلام الرئيسي فقط
add_action( 'pre_get_posts', 'az_filter_courses_main_query' );

function az_filter_courses_main_query( WP_Query $query ): void {
    // التأكد من أننا في واجهة الموقع وأن هذا هو الاستعلام الرئيسي لأرشيف الدورات
    if ( is_admin() || ! $query->is_main_query() || ! $query->is_post_type_archive( 'az_course' ) ) {
        return;
    }

    $meta_conditions = [];
    $tax_conditions  = [];

    // أ. معالجة تصفية المستوى (Taxonomy Filter)
    $level = sanitize_key( get_query_var( 'course_level' ) );
    if ( ! empty( $level ) && in_array( $level, [ 'beginner', 'intermediate', 'advanced' ], true ) ) {
        $tax_conditions[] = [
            'taxonomy' => 'az_course_level',
            'field'    => 'slug',
            'terms'    => $level,
        ];
    }

    // ب. معالجة تصفية السعر الأقصى (Meta Filter)
    $price_max = absint( get_query_var( 'course_price_max' ) );
    if ( $price_max > 0 ) {
        $meta_conditions[] = [
            'key'     => '_az_course_price',
            'value'   => $price_max,
            'type'    => 'NUMERIC',
            'compare' => 'set( 'tax_query', $tax_conditions );
    }

    // تطبيق شروط الميتا إن وجدت
    if ( ! empty( $meta_conditions ) ) {
        $query->set( 'meta_query', $meta_conditions );
    }

    // ضمان تفعيل الترقيم وعدد الدورات المعروضة في الصفحة
    $query->set( 'posts_per_page', 9 );
}

6. الأمان في متغيرات الاستعلام: الحماية من التلاعب وحقن الـ XSS

الكثير من المطورين يقعون في ثغرات أمنية فادحة بسبب التعامل الخاطئ مع متغيرات الاستعلام عند طباعتها في الصفحة:

// ❌ كود كارثي يفتح ثغرة Reflected Cross-Site Scripting (XSS):
$keyword = get_query_var( 's' );
echo "نتائج البحث عن: " . $keyword;
// لو مرر المهاجم: ?s=<script>alert(document.cookie)</script>
// هيتم تنفيذ كود جافاسكريبت في متصفح الزائر وسرقة بياناته فوراً!

القواعد الأمنية الذهبية للتعامل مع مخرجات Query Vars:

  1. الهروب دائماً عند الطباعة (Late Escaping): لا تطبع أي متغير قادم من get_query_var بدون تغليفه بدالة الهروب المناسبة لسياق العرض:
    • داخل نصوص HTML العادية: استخدم esc_html( get_query_var( 's' ) ).
    • داخل خصائص العناصر (Attributes مثل value أو placeholder): استخدم esc_attr( get_query_var( 's' ) ).
    • داخل الروابط (href أو src): استخدم esc_url( get_query_var( 'redirect_url' ) ).
  2. الحماية من هجمات تلوث المعلمات (HTTP Parameter Pollution): قد يحاول المهاجم تمرير مصفوفات في حقول متوقعة كنصوص (مثل: ?az_level[]=1&az_level[]=2) لتخريب استعلامات PHP. احرص دائماً على فحص is_string() أو is_array() قبل إجراء أي مقارنات شرطية.

7. دراسة حالة واقعية: تصفية 50,000 منتج بـ Query Vars وكاش Redis فائق السرعة

في متجر تجارة إلكترونية ضخم يعمل بنظام WooCommerce ويضم أكثر من 50,000 منتج بمئات السمات (الألوان، المقاسات، الماركات، الأسعار)، كانت صفحة التصفية (Shop Filter) تستغرق أكثر من 4.2 ثانية عند اختيار أي شرط تصفية! والسبب هو أن الإضافة السابقة كانت تنفذ استعلامات SQL ثقيلة ومعقدة بروابط عشوائية في كل نقرة.

إعادة الهيكلة المعمارية:

  1. قمنا بحصر وتوحيد كافة سمات التصفية في 5 متغيرات query_vars رسمية فقط (مثل: az_brand, az_size, az_color).
  2. أنشأنا خوارزمية لتوليد بصمة كاش موحدة (Cache Key) بالاعتماد على مصفوفة query_vars المنقحة والمرتبة أبجدياً: $cache_key = 'az_filter_' . md5( serialize( $sanitized_vars ) );.
  3. قمنا بحفظ نتائج الاستعلامات الشائعة مسبقاً في Redis Object Cache لمدة 6 ساعات.
  4. تم استدعاء النتائج المخزنة فوراً عند تطابق المتغيرات، وتحديث الفهارس فقط عند تعديل المنتجات في لوحة التحكم.

النتيجة بالأرقام: انخفض زمن تحميل صفحة تصفية المنتجات من 4.2 ثوانٍ إلى 35 ميلي ثانية فقط (أسرع بأكثر من 120 ضعفاً!)، مع انخفاض استهلاك معالج قاعدة البيانات بنسبة 78% تحت ضغط آلاف المتسوقين المتزامنين في أوقات التخفيضات الكبرى!

8. الوصايا العشر لمهندسي ووردبريس عند التعامل مع Query Vars

عشان كودك يكون بمثابة معيار ذهبي في النظافة، السرعة، والأمان، التزم بالوصايا العشر التالية في كل مشروع:

  1. لا تقرأ من $_GET مباشرة في القوالب: اعتمد دائماً على get_query_var() بعد تسجيل متغيراتك في القائمة البيضاء للنواة.
  2. استخدم بادئة فريدة لمتغيراتك المخصصة: أضف دائماً بادئة خاصة بإضافتك (مثل az_) لتفادي التصادم مع المتغيرات المحجوزة للنواة.
  3. احذر من الأسماء المحجوزة (Reserved Terms): تجنب تماماً استخدام كلمات مثل name, p, year, author لمتغيراتك الخاصة حتى لا تكسر الاستعلام وتسبب أخطاء 404.
  4. طبق التطهير المتأخر (Late Escaping): غلف كل متغير بدوال الهروب المناسبة (esc_html, esc_attr) عند طباعته في أي مكان بصفحة الـ HTML.
  5. تحقق من القيم عبر القوائم البيضاء (Enum Validation): إذا كان المتغير يقبل خيارات محددة، قارن القيمة بمصفوفة ثابتة مسموح بها قبل استخدامها.
  6. استفد من pre_get_posts لتطبيق المتغيرات: عدل الاستعلام الرئيسي في مكانه بدلاً من تشغيل استعلام new WP_Query مكرر في صفحة الأرشيف.
  7. استخدم absint للمعرفات وأرقام الصفحات: لضمان تحويل القيمة لرقم صحيح موجب ومنع أي محاولات لحقن نصوص أو أرقام سالبة.
  8. حافظ على المتغيرات أثناء ترقيم الصفحات: استخدم add_query_arg() لتمرير متغيرات التصفية النشطة إلى روابط الصفحات التالية لضمان عدم ضياع شروط البحث عند الانتقال للصفحة 2.
  9. افحص نوع البيانات لمنع Parameter Pollution: تأكد من أن القيمة نصية وليست مصفوفة غير متوقعة عبر is_string().
  10. كّش الاستعلامات المعتمدة على Query Vars: في المتاجر الكبيرة، استخدم التخزين المؤقت Transients أو Redis لتقليل الضغط على محرك قاعدة البيانات.

واحدة من أروع القدرات المعمارية في ووردبريس هي دمج Query Vars مع قواعد الـ Rewrite لتوليد روابط أنيقة للغاية بدلاً من الروابط القبيحة المليئة بعلامات الاستفهام والـ Ampersands. بدلاً من أن يرى الزائر رابطاً مثل:

abozaid.local/courses/?az_level=advanced&az_track=wordpress-dev&paged=2

يمكننا تحويله إلى رابط جذاب وصديق لمحركات البحث (SEO Friendly) بالشكل التالي:

abozaid.local/courses/level/advanced/track/wordpress-dev/page/2/

كود الربط المعماري المتكامل:

// 1. تسجيل المتغيرات المخصصة
add_filter( 'query_vars', function( array $vars ): array {
    $vars[] = 'az_level';
    $vars[] = 'az_track';
    return $vars;
});

// 2. تسجيل قواعد التعابير النمطية لربط المسارات بالمتغيرات
add_action( 'init', function(): void {
    // أ. قاعدة الترقيم مع وجود المستويين معاً
    add_rewrite_rule(
        '^courses/level/([^/]+)/track/([^/]+)/page/([0-9]+)/?$',
        'index.php?post_type=az_course&az_level=$matches[1]&az_track=$matches[2]&paged=$matches[3]',
        'top'
    );

    // ب. قاعدة الصفحة الأولى مع وجود المستويين معاً
    add_rewrite_rule(
        '^courses/level/([^/]+)/track/([^/]+)/?$',
        'index.php?post_type=az_course&az_level=$matches[1]&az_track=$matches[2]',
        'top'
    );
});

هذا التكامل المعماري يتيح لك بناء واجهات مستخدم احترافية تحافظ على نظافة الروابط وتوفر تجربة استثنائية للزوار ومحركات البحث على حد سواء.

10. تكامل Query Vars مع واجهات التطبيقات البرمجية (REST API & Headless)

في التطبيقات الحديثة المبنية بـ React أو Next.js أو Vue مع ووردبريس كـ Headless CMS، لا تنتهي أهمية query_vars، بل تنتقل إلى طبقة واجهة برمجة التطبيقات (REST API). عندما تستدعي مساراً مثل /wp-json/wp/v2/courses?level=advanced، يقوم خادم WP_REST_Server بفحص المعاملات بنفس الفلسفة المعمارية الصارمة:

  • دوال التحقق (Validation Callbacks): التحقق من أن القيمة تتبع النمط المتوقع قبل معالجتها:
    'validate_callback' => function( $param ) { return in_array( $param, ['beginner', 'advanced'], true ); }
  • دوال التطهير (Sanitization Callbacks): تنقية المدخلات تلقائياً:
    'sanitize_callback' => 'sanitize_key'
  • مزامنة حالة المتصفح (Browser URL Sync): في تطبيقات الواجهة الأمامية، يقوم تطبيق React بقراءة معلمات URLSearchParams من شريط المتصفح وتمريرها في طلب الـ fetch() للـ REST API، ليعود ووردبريس بالنتائج المصفاة بسرعة فائقة متوافقة مع الـ Object Cache.

نصيحة معمارية ذهبية للأداء عند استخدام Transients مع Query Vars: عند حفظ نتائج التصفية المستندة لمتغيرات الاستعلام في الكاش المؤقت، احرص على تقصير مفتاح الكاش؛ لأن قاعدة بيانات ووردبريس تحدد طول عمود option_name بـ 191 حرفاً كحد أقصى. استخدام دالة تشفير سريعة مثل md5() أو sha1() لتحويل مصفوفة المتغيرات إلى سلسلة أحادية بطول 32 حرفاً يضمن عدم تجاوز الحد الأقصى للمفتاح ويسرع عملية البحث في جداول قاعدة البيانات ومفاتيح Redis بشكل ملحوظ.

الأسئلة الشائعة حول متغيرات الاستعلام في ووردبريس (FAQ)

س1: ما هو الفرق الأساسي بين $_GET و get_query_var() في ووردبريس؟

مصفوفة $_GET تحتوي على المدخلات الخام الممررة في الرابط بعد علامة الاستفهام فقط ولا تشمل المتغيرات المستخرجة من الروابط الدائمة المنمقة (Pretty Permalinks). بينما get_query_var() تقرأ المتغير بعد فحصه ومطابقته بواسطة محرك الـ Rewrite والتحقق من وجوده في القائمة البيضاء للنواة، مما يجعله أكثر أماناً وتوافقاً مع بنية الموقع.

س2: لماذا تعيد دالة get_query_var قيمة فارغة رغم أن المتغير موجود في شريط العنوان؟

لأن ووردبريس يطبق نظام القائمة البيضاء الصارم؛ لن تتعرف النواة على المتغير ولن تملأه في مصفوفة query_vars إلا إذا قمت بتسجيله صراحة عبر فلتر query_vars في ملف functions.php أو داخل إضافتك البرمجية.

س3: كيف أمرر متغيراً مخصصاً داخل قاعدة add_rewrite_rule؟

أولاً تسجل المتغير في فلتر query_vars، ثم في دالة add_rewrite_rule() توجه التعبير النمطي للرابط الداخلي متضمناً اسم المتغير: 'index.php?my_var=$matches[1]'، لتقوم النواة تلقائياً بالتقاط القيمة وتعبئتها في الذاكرة.

س4: هل يمكن استخدام دالة set_query_var لتعديل الاستعلام الرئيسي؟

نعم، يمكنك استدعاء set_query_var( 'key', 'value' ) أو استخدام $query->set( 'key', 'value' ) داخل خطاف pre_get_posts لفرض معلمات استعلام إضافية أو تعديل ترتيب المنشورات برمجياً قبل تنفيذ استعلام MySQL.

س5: ما هي مخاطر استخدام أسماء المتغيرات المحجوزة للنواة (Reserved Query Vars)؟

استخدام أسماء محجوزة (مثل name أو year أو category_name) لأغراض أخرى في إضافتك يضلل كائن WP_Query؛ حيث سيفسرها ووردبريس وفق منطقه الداخلي، مما يؤدي إلى فشل استعلام الصفحة وظهور أخطاء 404 مفاجئة أو عرض مقالات غير ذات صلة.

س6: كيف أحافظ على متغيرات التصفية الحالية عند الانتقال بين صفحات الترقيم Pagination؟

عن طريق استخدام دالة add_query_arg() لتوليد روابط الترقيم؛ حيث تقوم هذه الدالة بدمج معلمات التصفية الحالية المعتمدة مع رقم الصفحة الجديدة تلقائياً دون فقدان شروط الفرز التي اختارها المستخدم.

س7: هل يتم حفظ متغيرات Query Vars في قاعدة البيانات؟

لا، متغيرات query_vars تعيش حصرياً في ذاكرة الخادم RAM أثناء دورة حياة الطلب الحالي فقط (Request Lifecycle)، ويتم توليدها وتنقيتها مع كل زيارة وتنتهي بمجرد اكتمال إرسال صفحة الـ HTML للمتصفح.

س8: كيف أتحقق من أن المتغير الممرر يمثل رقماً صحيحاً موجباً؟

باستخدام دالة النواة القياسية absint( get_query_var( 'my_number' ) )؛ هذه الدالة تقوم بتحويل المدخل إلى رقم صحيح وتتخلص من أي علامات سالبة أو نصوص برمجية خبيثة.

س9: ما الفرق بين دالة get_query_var ودالة wp_is_mobile في معالجة الطلبات؟

دالة get_query_var() متخصصة في قراءة معلمات واستعلامات الرابط الداخلي المعتمدة من النواة، بينما دالة wp_is_mobile() تفحص ترويسة User-Agent القادمة من المتصفح لتحديد نوع جهاز الزائر (هاتف أم حاسوب).

س10: هل يمكن لمتغير الاستعلام أن يحتوي على مصفوفة متعددة القيم؟

نعم، إذا تم تمرير المعامل بصيغة مصفوفة في الرابط (مثل ?az_tags[]=php&az_tags[]=react)، ستعيد دالة get_query_var مصفوفة، ويجب عليك تنقيتها بواسطة array_map( 'sanitize_text_field', (array) get_query_var('az_tags') ) لضمان نظافة كل عنصر.

س11: كيف أطبع قيمة متغير البحث في مربع الإدخال بأمان تام؟

باستخدام الدالة المخصصة للبحث: get_search_query() أو esc_attr( get_query_var( 's' ) ) داخل خاصية value لعنصر الإدخال، لمنع إغلاق الوسم وتنفيذ هجمات الـ XSS.

س12: ما هو دور خاصية $wp_query->query_vars_hash؟

هي بصمة تشفير داخلية (MD5 Hash) يولدها كلاس WP_Query لمصفوفة المتغيرات الحالية؛ وتستخدمها النواة للتحقق من عدم تكرار نفس الاستعلام ومقارنة الطلبات في الذاكرة لتسريع الأداء.

س13: كيف أحذف متغيراً من مصفوفة الاستعلام برمجياً قبل تنفيذ الاستعلام؟

يمكن استخدام $query->set( 'variable_name', '' ) أو إزالة المفتاح عبر unset( $query->query_vars['variable_name'] ) داخل خطاف pre_get_posts لمنع النواة من تطبيق هذا الشرط في استعلام MySQL.

س14: هل تؤثر كثرة متغيرات Query Vars المسجلة على أداء الموقع؟

لا تؤثر إطلاقاً على سرعة المعالجة؛ حيث تقوم PHP بالبحث في مصفوفة القائمة البيضاء في أجزاء متناهية الصغر من الميكروثانية في الرام. الأثر الوحيد يأتي مما تفعله بهذه المتغيرات في استعلامات قاعدة البيانات اللاحقة.

س15: كيف أتعامل مع التواريخ الممررة في متغيرات الاستعلام؟

ووردبريس يوفر متغيرات جاهزة مثل year وmonthnum وday. وإذا استخدمت متغيراً مخصصاً لتاريخ محدد (مثل az_date)، تحقق من صحة تركيبه عبر DateTime::createFromFormat( 'Y-m-d', $date ) قبل تمريره للاستعلام.

س16: كيف أختبر كافة متغيرات الاستعلام النشطة في الصفحة أثناء التطوير؟

عبر إضافة Query Monitor والاطلاع على تبويب Request، أو برمجياً عبر كتابة dump( $GLOBALS['wp_query']->query_vars ); في ملف القالب لمعاينة كافة المتغيرات وقيمها المعتمدة في الطلب الحالي.

س17: ما هو الفرق المعماري بين get_query_var و $_REQUEST في ووردبريس؟

مصفوفة $_REQUEST تجمع مدخلات $_GET و $_POST و $_COOKIE معاً بشكل عشوائي وغير منقح، وهي ممارسة محظورة أمنياً في ووردبريس لسهولة التلاعب بها وثغرات CSRF. بينما get_query_var() تقرأ حصرياً المتغيرات المعتمدة بعد مرورها بمحطة التحليل والتنقية بالقائمة البيضاء للنواة.

س18: كيف أتحقق برمجياً مما إذا كان متغير معين قد تم تمريره بالفعل أم أنه افتراضي؟

يمكن استخدام دالة get_query_var( 'my_var', null ) وتمرير null كقيمة افتراضية؛ فإذا أعادت الدالة null فهذا يعني أن المتغير لم يُمرر إطلاقاً في الطلب الحالي، وإذا أعادت قيمة أخرى فيمكنك معالجتها كقيمة مرسلة من المستخدم.

س19: هل يؤثر استخدام Query Vars المخصصة على الكاش في شبكات CDN مثل Cloudflare؟

نعم؛ شبكات CDN تعتبر كل رابط يحتوي على Query String مختلف بمثابة صفحة فريدة (Cache Miss). لذلك، عند استخدام التصفية الكثيفة، يفضل دمج Query Vars في مسارات منمقة (Pretty Permalinks) أو ضبط قواعد الـ CDN لتجاهل المعلمات غير المؤثرة على محتوى الصفحة.

س20: كيف أتعامل مع المتغيرات المخصصة داخل لوحة التحكم Admin Panel؟

في لوحة التحكم، لا تعمل دورة parse_request الكاملة لأن الطلب يستهدف ملفات الإدارة مباشرة (مثل edit.php). لذلك في صفحات الإدارة، يتم قراءة المعلمات المنقحة باستخدام دوال مساعدة مع sanitize_text_field( wp_unslash( $_GET['filter_val'] ?? '' ) ).

المصادر والمراجع الرسمية المعتمدة

أكمل المسار

الصورة الرمزية لـ Mohamed Abozaid

م. محمد أبو زيد

WordPress Architect & Enterprise Consultant

مهندس برمجيات متخصص في تطوير حلول ووردبريس المتقدمة، معمارية Block Themes، ومحرر Gutenberg، وتحسين الأداء لمواقع الشركات الكبرى في مصر والخليج العربي.


اترك تعليقاً