PHP overloading זה בעצם כינוי ליכולת שיש לנו ב-PHP ליצור מתודות ותכונות חדשות לאובייקט כאשר היצירה נעשית באופן שקוף ביותר למשתמש. ואם זה נשמע מסובך, אני אדגים באמצעות הצגה של אימפלמנטציה של registry. ואם זה נשמע מסובך, פשוט תמשיכו לקרוא והכל יהיה מובן, אני מבטיח.
אז קודם כל, מה זה registry? מדובר בסוג של אובייקט שתפקידו לאחסן ולכתוב מידע לאובייקט גלובלי. יש כמה סוגים של registry ואפילו design pattern מסודר שאמורים להשתמש בו. אני אוהב להשתמש, כשצריך ב- registry פשוט מאד. משהו שאני יכול להשתמש בו באופן הבא:
$registry = new Registry();
$registry->someProperty; //get
$registry->someProperty = 'whatever'; //set
כלומר אם אני קורא לתכונה מסוימת – לקבל אותה (אם היא קיימת) ואם אני רוצה לעשות set up, אז אני פשוט עושה את זה. זה registry פשוט. יש כאלו שיגידו ששימוש ב-registry הוא סימן לתכנות גרוע, בחלק מהמקרים הם גם יהיו צודקים – לא נכנס לזה עכשיו. לפעמים במערכות קטנות יש צידוק ל-registry שמאחסן מידע אד הוקי.
השאלה היא – איך אני עושה את זה? איך אני יוצר class שיודע לקרוא לכל תכונה שיש בו באמצעות שימוש בשם התכונה?
$registry->someProperty; //get
הרי במקום someProperty יכול להיות שלל של properties אחרים. יכול להיות שיש ב-class שלי גם מאתיים כאלו – אז איך עושים את זה? כאן נכנסת תכונת ה-overloading – ומתודות 'הקסם' set__ ו get__. מתודת get__ עובדת באופן אוטומטי בכל פעם שמתבצעת קריאה למתודה/תכונה שעדיין לא קיימת, ומתודת set__ עובדת באופן אוטומטי בכל פעם שמתבצעת השמה לתכונה שעדיין לא קיימת.
מבולבלים? הנה הדוגמה המיוחלת:
class Registry {
public $vars = array();
public function __construct() {
$this->vars = array(
'db_name' => 'dbNAME',
'db_user' => 'dbUSER',
'db_password' => 'dbPWD',
'db_host' => 'localhost',
'table_name' => 'tableNAME'
);
}
public function __set($key, $val) {
$this->vars[$key] = $val;
}
public function __get($key) {
if (array_key_exists($key, $this->vars)) {
return $this->vars[$key];
} else {
return null;
}
}
}
מה קורה פה? בקונסטרקטור אני יוצר מערך שבו יש מידע בתצורת key value. אם אני מבצע קריאה למתודה, למשל
$registry = new Registry();
$registry->table_name;
כמובן שאין לי מתודת (או תכונה) בשם table_name, ואז get נכנסת לפעולה ומחזירה לי את האיבר במערך שנקרא table_name.
אם אני ארצה להכניס ל-registry משהו, אני אעשה את הדבר הבא:
$registry = new Registry();
$registry->whatever = 'some_value'
ואז מתודת set__ נכנסת לפעולה כמובן.
בקלאס הדוגמה הקטן שלי, כל מה שמתודות הקסם האלו, שפועלות באופן אוטומטי עושות, הוא פשוט להכניס או לשלוף מידע ממערך שאותו אני מאכלס בקונסטרקטור. כמובן שאפשר לעשות עם overloading הרבה יותר.
בנוגע ל-registry, יש דרכים יותר נכונות לממש אותו ובאחד המאמרים הבאים אדבר עליה.