__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 שוטפים, למימוש העברת קריאות לשיטות או לבניית בוני שאילתות דינמיים, שבהם שמות השיטות מתורגמים לפעולות במסד הנתונים. הן מאפשרות לאובייקטים שלך להגיב בצורה חכמה לכל קריאה לשיטה, אפילו לכאלה שלא הגדרת במפורש.
אתגר
קלבואו נבנה לקוח 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 כארגומנט
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח $thisמתודותמאפייניםבנאי (__construct)הורס (__destruct)חזרה: מחשבון פשוט4ירושה
ירושה בסיסיתמילת המפתח parent::דריסת מתודותמילת המפתח finalמחלקות מופשטותסיכום – היררכיית עובדים7כימוס
ציבורי, מוגן, פרטימפרטי גישה לעומקמתודות גישה ועדכוןהסתרת מידעקידום פרמטרים בבנאי (8.0)סיכום – מערכת רישומי תלמידים2מרחבי שמות וטעינה אוטומטית
מבוא למרחבי שמותמילת המפתח useתקן הטעינה האוטומטית PSR-4הטוען האוטומטי של Composerסיכום – פרויקט מאורגן5ממשקים וחוזים
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםממשק לעומת מחלקה מופשטתרמזי טיפוסים עם ממשקיםסיכום - מחשבון צורות8מתודות קסם
מבוא למתודות קסם__toString ו־__debugInfo__get, __set, __isset, __unset__call ו־__callStatic__clone ושיבוט אובייקטים__serialize ו־__unserializeסיכום – אוסף מותאם אישית3מאפייני מחלקה
מאפייני מופע לעומת מאפיינים סטטייםקבועים במחלקותמתודות ומאפיינים סטטייםמאפיינים פרטיים ומוגניםמאפיינים לקריאה בלבד (PHP 8.1)סיכום – מנהל חשבון בנק6פולימורפיזם
בחינה מחדש של דריסת מתודותפולימורפיזם באמצעות ממשקיםרמזי טיפוסים וטיפוסי איחודקישור סטטי מאוחרסיכום — מעבד תשלומיםתרגלו בעצמכם: קומפיילר PHP אונליין