Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

__call و __callStatic

جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 47 من 91.

تمامًا كما يعترض __get() و__set() الوصول إلى الخصائص، يعترض الأسلوبان __call() و__callStatic() استدعاءات الأساليب. ويتم تشغيلهما عند استدعاء أسلوب غير موجود أو غير متاح على كائن أو صنف.

تتعامل الدالة __call() مع استدعاءات method الخاصة بـ instance. وتتلقى اسم method وarray من arguments:

<?php
class Messenger {
    public function __call(string $name, array $arguments): string {
        return "Called '$name' with: " . implode(", ", $arguments);
    }
}

$msg = new Messenger();
echo $msg->sendEmail("Hello", "World");

الناتج:

Called 'sendEmail' with: Hello, World

لاستدعاءات الطريقة الساكنة، استخدم __callStatic(). لاحظ أنه يجب التصريح عنها على أنها static:

<?php
class QueryBuilder {
    public static function __callStatic(string $name, array $arguments): string {
        if (str_starts_with($name, "findBy")) {
            $field = substr($name, 6);
            return "Finding by $field: " . $arguments[0];
        }
        return "Unknown method: $name";
    }
}

echo QueryBuilder::findByEmail("test@example.com");

المخرجات:

Finding by Email: test@example.com

هذه magic methods قوية لإنشاء واجهات API سلسة، وتنفيذ تمرير method، أو بناء منشئات استعلامات dynamic حيث تُترجم أسماء method إلى عمليات قاعدة البيانات. وهي تتيح لكائناتك الاستجابة بذكاء لأي استدعاء method، حتى تلك التي لم تعرّفها صراحةً.

challenge icon

التحدي

سهل

لنَبْنِ عميل API dynamic يستخدم magic methods للتعامل مع استدعاءات method بمرونة. ستنشئ class تعترض كلاً من استدعاءات method الخاصة بـ instance وstatic، وتحولها إلى استجابات تشبه API ذات معنى دون تعريف كل method بشكل صريح.

ستنظّم شفرتك عبر ملفين:

  • ApiClient.php: أنشئ class باسم ApiClient يحاكي تفاعلات API باستخدام magic methods. يجب أن يحتوي class على الخاصية الخاصة $baseUrl، ويتم تعيينها من خلال الباني. Implement اثنين من magic methods:
    • __call(): يتعامل مع استدعاءات method الخاصة بـ instance. عند استدعاء method يبدأ بـ get (مثل getUsers أو getPosts)، استخرج اسم المورد (الجزء الذي يأتي بعد "get") وأعد "GET [baseUrl]/[resource]: [arguments joined by comma]". يجب تحويل اسم المورد إلى lowercase. إذا لم يبدأ method بـ "get"، فأعد "Unknown action: [methodName]".
    • __callStatic(): يتعامل مع استدعاءات method static. عند استدعاء method يبدأ بـ create (مثل createUser)، استخرج اسم المورد وأعد "POST /[resource]: [arguments joined by comma]". يجب أن يكون اسم المورد lowercase. بالنسبة إلى methods التي تبدأ بـ delete، أعد "DELETE /[resource]: [first argument]". بالنسبة إلى أي method آخر، أعد "Static action not supported: [methodName]".
  • main.php: ضمّن ملف ApiClient. ستتلقى ثلاثة مدخلات: عنوان URL أساسي، ومعرّف مورد، وقيمة. أنشئ instance من ApiClient باستخدام عنوان URL الأساسي. ثم اطبع أربعة أسطر:
    • استدعِ method get dynamic باستخدام معرّف المورد كلاحقة لاسم method (على سبيل المثال، إذا كان المورد هو "Users"، فاستدعِ getUsers) مع تمرير القيمة كوسيطة
    • استدعِ getProducts بوسيطتين: "electronics" و"active"
    • استدعِ method static createOrder مع تمرير القيمة كوسيطة
    • استدعِ method static deleteItem مع تمرير معرّف المورد كوسيطة

تتيح magic methods لعميل API الاستجابة لأي استدعاء method بشكل dynamic. بدلاً من تعريف getUsers() وgetPosts() وgetProducts() وعشرات methods الأخرى، يتولى method واحد هو __call() معالجتها جميعاً من خلال فحص اسم method واستخراج المعلومات ذات الصلة.

جرّب بنفسك

<?php

require_once 'ApiClient.php';

// اقرأ المدخلات
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: أنشئ مثيلاً من ApiClient باستخدام عنوان URL الأساسي

// TODO: استدعِ طريقة get ديناميكية باستخدام المورد كلاحقة لاسم الطريقة
// تلميح: استخدم استدعاءات الطرق المتغيرة مثل $api->{"get" . $resource}($value)

// TODO: استدعِ getProducts مع وسيطين: "electronics" و "active"

// TODO: استدعِ الطريقة الثابتة createOrder مع القيمة كوسيط
// تلميح: استخدم ApiClient::createOrder($value)

// TODO: استدعِ الطريقة الثابتة deleteItem مع المورد كوسيط

?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم PHP عبر الإنترنت