קישור סטטי מאוחר
חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 36 מתוך 91.
כשמשתמשים ב-self:: במחלקת אב, הוא תמיד מתייחס למחלקה שבה הוא נכתב, ולא למחלקה שבה נעשה בפועל שימוש. הדבר עלול לגרום להתנהגות לא צפויה בירושה. קישור סטטי מאוחר פותר את הבעיה באמצעות מילת המפתח static::.
שקול את הדוגמה הזו, שבה self:: לא פועל כמצופה:
<?php
class ParentClass {
public static function create() {
return new self();
}
public static function getClassName() {
return self::class;
}
}
class ChildClass extends ParentClass {}
$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();
פלט:
ParentClass
ParentClassלמרות שקראנו ל־ChildClass::create(), קיבלנו אובייקט ParentClass, כי self:: נפתר בזמן ההידור. עכשיו נשתמש במקום זאת ב־static:::
<?php
class ParentClass {
public static function create() {
return new static();
}
public static function getClassName() {
return static::class;
}
}
class ChildClass extends ParentClass {}
$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();
פלט:
ChildClass
ChildClassעם static::, PHP ממתין עד לזמן הריצה כדי לקבוע באיזו מחלקה להשתמש. הדבר נקרא קישור "מאוחר" מכיוון שההחלטה נדחית. הוא חיוני לשיטות מפעל ולכל שיטה סטטית שאמורה לכבד ירושה.
נקודה חשובה: השתמשו ב-static:: במקום ב-self:: כשרוצים שמחלקות יורשות יירשו ויתאימו אישית התנהגות סטטית כראוי.
אתגר
קלנבנה מערכת לרישום מודלים שמדגימה את העוצמה של קישור סטטי מאוחר. תיצרו מחלקת בסיס Model עם מתודת מפעל שמחלקות יורשות יכולות לרשת, ובזכות static::, כל מחלקה יורשת תיצור מופעים של עצמה כראוי במקום מופעים של מחלקת האב.
תארגנו את הקוד בארבעה קבצים:
Model.php: צרו מחלקת בסיסModelעם מאפיין סטטי מוגן$tableNameשערכו"models". הוסיפו מתודה סטטיתcreate()שמשתמשת ב-new static()כדי להחזיר מופע חדש של המחלקה שקראה לה. הוסיפו מתודה סטטית נוספתgetTable()שמחזירה אתstatic::$tableName. לבסוף, הוסיפו מתודהdescribe()שמחזירה את"[ClassName] from table [tableName]"באמצעותstatic::classו-static::$tableName.User.php: צרו מחלקתUserשיורשת אתModel. כללו את קובץ מחלקת האב. דרסו את המאפיין הסטטי$tableNameוהגדירו את ערכו ל-"users". המחלקה יורשת את כל המתודות מ-Modelללא שינויים.Product.php: צרו מחלקתProductשיורשת אתModel. כללו את קובץ מחלקת האב. דרסו את המאפיין הסטטי$tableNameוהגדירו את ערכו ל-"products". גם כאן, המחלקה יורשת את כל המתודות ממחלקת האב.main.php: כללו את הקבצים של User ושל Product. השתמשו במתודת המפעל המורשתcreate()כדי ליצור מופעים גם שלUserוגם שלProduct. עבור כל מופע, קראו ל-describe()והדפיסו את התוצאה בשורה נפרדת. לאחר מכן, הדפיסו את שם הטבלה של כל מחלקה באמצעותUser::getTable()ו-Product::getTable(), כל אחד בשורה נפרדת.
הקסם כאן הוא שהמתודות create() ו-getTable() מוגדרות רק במחלקת האב Model, ובכל זאת הן פועלות כראוי עם מחלקות יורשות, משום ש-static:: דוחה את הקישור עד לזמן הריצה. כשתקראו ל-User::create(), PHP תיצור מופע של User, ולא מופע של Model, משום ש-static:: מתייחס למחלקה שנקראה בפועל.
הפלט שלכם אמור להציג ארבע שורות: התיאור של מופע User, התיאור של מופע Product, שם הטבלה של User ושם הטבלה של Product.
נסו בעצמכם
<?php
require_once 'User.php';
require_once 'Product.php';
// TODO: השתמשו במתודת המפעל create() שעברה בירושה כדי ליצור מופע של User
// TODO: השתמשו במתודת המפעל create() שעברה בירושה כדי ליצור מופע של Product
// TODO: קראו ל-describe() על המופע של User והדפיסו את התוצאה
// TODO: קראו ל-describe() על המופע של Product והדפיסו את התוצאה
// TODO: הדפיסו את User::getTable()
// TODO: הדפיסו את Product::getTable()
?>השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין