Menu

מחלקות ואובייקטים ב-PHP: מאפיינים, מתודות ו-$this

מחלקה ב-PHP היא תבנית שמוצהרת עם class Name { }, ו-new Name() יוצר ממנה אובייקט. למדו מאפיינים, מתודות, $this, public/private/protected, מאפיינים עם טיפוס ו-readonly, __toString, ולמה הצבה של אובייקט לא מעתיקה אותו.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

מחלקה ב-PHP מוצהרת עם class Name { ... } ומחזיקה מאפיינים (משתנים) ומתודות (פונקציות). new Name() יוצר ממנה אובייקט, ו--> קורא מאפיין או קורא למתודה: $user->name, $user->greet().

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

מאפיינים ומתודות

מאפיין מוצהר עם מילת מפתח של רמת גישה, טיפוס אופציונלי וערך ברירת מחדל אופציונלי. מתודה היא פונקציה בתוך המחלקה. בתוך מתודה, $this הוא האובייקט שעליו נקראה המתודה, ולכן $this->balance קורא את היתרה של האובייקט הזה.

כל אובייקט שומר $balance משלו: הפקדה ל-$a לא נוגעת ב-$b. הגדרה של מאפיינים אחד אחד אחרי new נעשית מייגעת; בנאי מקבל במקום זאת את ערכי ההתחלה כארגומנטים.

public, private ו-protected

רמת הגישה קובעת מי יכול לגעת במאפיין או לקרוא למתודה:

מילת מפתחנגיש מתוך
publicכל מקום
protectedהמחלקה עצמה ומחלקות שמרחיבות אותה
privateרק המחלקה שמצהירה עליו

הפיכת מאפיין ל-private וחשיפת מתודות היא הדרך שבה מחלקה מגינה על הכללים שלה. כאן היתרה יכולה להשתנות רק דרך deposit() ו-withdraw(), שמסרבות לסכומים לא תקינים:

קריאה של המאפיין הפרטי מחוץ למחלקה היא לא אזהרה, היא Error:

מאפיינים עם טיפוס וערכים לא מאותחלים

מאפיין עם טיפוס בלי ערך ברירת מחדל מתחיל לא מאותחל, וזה שונה מ-null. קריאה שלו לפני שמשהו הוצב בו זורקת Error. או שתתנו לו ברירת מחדל, או שתציבו אותו בבנאי, או שתהפכו אותו ל-nullable עם ?Type ו-= null.

הטיפוסים נאכפים בהצבה. במצב ברירת המחדל (לא מחמיר), $p->stock = '7' ממיר את המחרוזת המספרית ל-7, בעוד $p->stock = 'many' זורק TypeError.

מאפייני readonly

מאפיין readonly (PHP 8.1) אפשר לכתוב פעם אחת, מתוך המחלקה, ואז אף פעם לא שוב. זו הדרך הרגילה לבנות אובייקטי ערך כמו סכומי כסף או מזהים. PHP 8.2 הוסיפה את readonly class, שהופכת כל מאפיין ל-readonly.

למאפיין readonly חייב להיות טיפוס, ואין לו ערך ברירת מחדל. אם אתם צריכים עותק משונה, צרו אובייקט חדש (new Order('B-2002')) במקום לערוך את הישן.

הדפסת אובייקט עם __toString

echo $object עובד רק כשהמחלקה מגדירה __toString(). המתודה מחזירה את המחרוזת ש-PHP צריכה להשתמש בה בכל פעם שהאובייקט מטופל כטקסט: ב-echo, בשרשור מחרוזות, ב-"{$object}".

בלי __toString, echo $object זורק Error ("Object of class Money could not be converted to string"). לדיבאג, print_r() ו-var_dump() עובדות על כל אובייקט ומציגות גם מאפיינים פרטיים; ראו var_dump ו-print_r.

הצבה של אובייקט לא מעתיקה אותו

זו הטעות שעוקצת את רוב מי שמגיעים ממערכים. הצבה של מערך מעתיקה אותו. הצבה של אובייקט מעתיקה רק את הידית: שני המשתנים מצביעים אז על אותו אובייקט.

clone יוצר עותק רדוד: אם מאפיין מחזיק אובייקט אחר, שני העותקים עדיין חולקים את האובייקט הפנימי הזה. === מתקיים רק לאותו אובייקט, בעוד == משווה את ערכי המאפיינים של שני אובייקטים מאותה מחלקה. העברה של אובייקט לפונקציה עובדת כמו הצבה, ולכן פונקציה יכולה לשנות את האובייקט שהיא מקבלת.

שאלות נפוצות

איך יוצרים אובייקט ממחלקה ב-PHP?

השתמשו ב-new עם שם המחלקה: $user = new User();. אם למחלקה יש בנאי, העבירו את הארגומנטים שלו בסוגריים, כמו ב-new User('Ada'). אחר כך קוראים למתודות ולמאפיינים עם אופרטור החץ: $user->name, $user->greet().

מה המשמעות של $this ב-PHP?

$this הוא האובייקט שעליו נקראה המתודה הנוכחית. בתוך $ada->greet(), $this הוא $ada, ולכן $this->name קורא את השם של Ada. הוא קיים רק בתוך מתודות שאינן סטטיות.

מה ההבדל בין public, private ו-protected ב-PHP?

בחברי public אפשר להשתמש מכל מקום, בחברי private רק מתוך המחלקה שמצהירה עליהם, ובחברי protected מתוך המחלקה הזו ומתוך מחלקות הבת שלה. קריאה של מאפיין פרטי מבחוץ זורקת Error: Cannot access private property.

האם אובייקטים מועברים לפי הפניה ב-PHP?

משתנה מחזיק ידית לאובייקט, לא את האובייקט עצמו. $b = $a; מעתיק את הידית, ולכן שני המשתנים מצביעים על אותו אובייקט ושינוי דרך $b מופיע ב-$a. השתמשו ב-$b = clone $a; כדי לקבל עותק עצמאי.

מה זה מאפיין readonly ב-PHP?

מאפיין שמוצהר public readonly string $id; (PHP 8.1 ומעלה) אפשר להגדיר פעם אחת, מתוך המחלקה, ואף פעם לא לשנות אחר כך. כתיבה אליו בפעם השנייה זורקת Error: Cannot modify readonly property.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל