Menu
Coddy logo textTech

__call ו־__callStatic

חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 47 מתוך 91.

בדומה לכך ש־__get() ו־__set() מיירטות גישה למאפיינים, המתודות __call() ו־__callStatic() מיירטות קריאות למתודות. הן מופעלות כשקוראים למתודה שאינה קיימת או שאינה נגישה באובייקט או במחלקה.

המתודה __call() מטפלת בקריאות למתודות של מופע. היא מקבלת את שם המתודה ומערך של ארגומנטים:

<?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

השיטות הקסומות האלה עוצמתיות ליצירת ממשקי API שוטפים, למימוש העברת קריאות לשיטות או לבניית בוני שאילתות דינמיים, שבהם שמות השיטות מתורגמים לפעולות במסד הנתונים. הן מאפשרות לאובייקטים שלך להגיב בצורה חכמה לכל קריאה לשיטה, אפילו לכאלה שלא הגדרת במפורש.

challenge icon

אתגר

קל

בואו נבנה לקוח API דינמי שמשתמש בשיטות קסם כדי לטפל בקריאות לשיטות בגמישות. תיצרו מחלקה שמיירטת קריאות לשיטות של מופע וגם לשיטות סטטיות, ומתרגמת אותן לתגובות משמעותיות דמויות API, בלי להגדיר כל שיטה במפורש.

תארגנו את הקוד בשני קבצים:

  • ApiClient.php: צרו מחלקה בשם ApiClient שמדמה אינטראקציות עם API באמצעות שיטות קסם. למחלקה שלכם צריכה להיות תכונה פרטית $baseUrl שמוגדרת באמצעות הבנאי. ממשו שתי שיטות קסם:
    • __call(): מטפלת בקריאות לשיטות של מופע. כאשר קוראים לשיטה שמתחילה ב־get (כמו getUsers או getPosts), חלצו את שם המשאב (החלק שאחרי "get") והחזירו "GET [baseUrl]/[resource]: [arguments joined by comma]". יש להמיר את שם המשאב לאותיות קטנות. אם השיטה לא מתחילה ב־"get", החזירו "Unknown action: [methodName]".
    • __callStatic(): מטפלת בקריאות לשיטות סטטיות. כאשר קוראים לשיטה שמתחילה ב־create (כמו createUser), חלצו את שם המשאב והחזירו "POST /[resource]: [arguments joined by comma]". שם המשאב צריך להיות באותיות קטנות. עבור שיטות שמתחילות ב־delete, החזירו "DELETE /[resource]: [first argument]". עבור כל שיטה אחרת, החזירו "Static action not supported: [methodName]".
  • main.php: כללו את קובץ ApiClient. תקבלו שלושה קלטים: כתובת בסיס, מזהה משאב וערך. צרו מופע של ApiClient עם כתובת הבסיס. לאחר מכן הדפיסו ארבע שורות:
    • קראו לשיטת get דינמית באמצעות מזהה המשאב כסיומת של שם השיטה (למשל, אם המשאב הוא "Users", קראו ל־getUsers) והעבירו את הערך כארגומנט
    • קראו ל־getProducts עם שני ארגומנטים: "electronics" ו־"active"
    • קראו לשיטה הסטטית createOrder והעבירו את הערך כארגומנט
    • קראו לשיטה הסטטית deleteItem והעבירו את מזהה המשאב כארגומנט

שיטות הקסם מאפשרות ללקוח ה־API שלכם להגיב באופן דינמי לכל קריאה לשיטה. במקום להגדיר את getUsers(), getPosts(), getProducts() ועוד עשרות שיטות, שיטה יחידה __call() מטפלת בכולן באמצעות בדיקת שם השיטה וחילוץ המידע הרלוונטי.

נסו בעצמכם

<?php

require_once 'ApiClient.php';

// קרא את הקלטים
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: צור מופע של ApiClient עם כתובת ה-URL הבסיסית

// TODO: קרא למתודת get דינמית באמצעות resource כסיומת לשם המתודה
// רמז: השתמש בקריאות למתודה משתנה כמו $api->{"get" . $resource}($value)

// TODO: קרא ל-getProducts עם שני ארגומנטים: "electronics" ו-"active"

// TODO: קרא למתודה הסטטית createOrder עם value כארגומנט
// רמז: השתמש ב-ApiClient::createOrder($value)

// TODO: קרא למתודה הסטטית deleteItem עם resource כארגומנט

?>
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר PHP אונליין