אתה נמצא כאן יסודות השפה  >>  מחלקות ואובייקטים  >>  שמירת נתוני מחלקה

שמירת נתוני מחלקה

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

file name: class_x.inc
<?php
  class X
/*הגדרת המחלקה X.
נשמרת בקובץ נפרד.
*/

  {
     var $num;
  
     function X($n)
     {
        $this->num=$n;
     }
  
     function ShowNum()
     {
        echo "num=".$this->num;
     }
  }
?>

file name: object_save.php
<?php
  include "class_x.inc";
/*ייבוא של הגדרת המחלקה X.*/

  
  $x=new X(5);
/*יצירת אובייקט מהמחלקה.
יצירת המחלקה דורשת את הגדרת המחלקה.
*/

  $s=serialize($x);
/*הפונקציה serialize() מתרגמת את אובייקט המחלקה
למחרוזת בו היא שומרת את ערכיו ושמו.
*/

  $fp=fopen("object_info.dat","w+");
/*פותח את הקובץ object_info.dat לכתיבה.*/

  fputs($fp,$s);
/*שומר את המחרוזת של האובייקט
בתוך הקובץ.
*/

  fclose($fp);
/*סוגר את הקובץ.*/

?>

file name: object_load.php
<?php
  include "class_x.inc";
/*ייבוא של הגדרת המחלקה X.*/

  
  $s=implode("",@file("object_info.dat"));
/*$s מקבל את המחרוזת שמתארת את האובייקט ששמרנו.
הפונקציה file() קוראת את הקובץ לתוך מערך, שאיבריה
הם השורות בקובץ.
והפונקציה implode() "מדביקה" את איברי המערך יחד
למחרוזת אחת.
*/

  $x=unserialize($s);
/*יוצר את האובייקט ששמרנו מחדש,
ע"י תרגום המחרוזת למופע המחלקה.
התרגום דורש את הגדרת המחלקה.
*/

  $x->ShowNum();
/*שימוש באובייקט המחלקה.*/

?>

כאשר משתמשים בפונקציות לשמירת האובייקט, מופעלות באופן אוטומטי הפונקציות המיוחדות השמורות למחלקות, __sleep() ו-__wakeup().
הפונקציה __sleep() נקראית באופן אוטומטי ע"י serialize(), ותפקידה הוא לבצע מטלות לפני שמירת האובייקט: שינוי של משתנים לפני השמירה, סגירת משאבים פתוחים (קבצים, בסיסי נתונים וכו’), והכי חשוב להחזיר מערך של הנתונים שאותם רוצים לשמור (כך למשל ניתן להחזיר רק את הנתונים ההכרחיים ולא לשמור נתונים שלא נחוצים).
הפונקציה __wakeup() נקראית באופן אוטומטי ע"י unserialize(), ותפקידה הוא לבצע מטלות לשם טעינת האובייקט: שינוי של משתנים אחרי הטעינה, פתיחת משאבים (קבצים, בסיסי נתונים וכו’), ומילוי ערכים למשתני מחלקה שלא נשמרו.
בדר"כ, לא מרבים לשכתב פונקציות אלו, אלא אם כן מדובר במחלקה גדולה ומורכבת (עם משאבים של קבצים פתוחים ובסיסי נתונים).


תגובות בנושא

האם זה אומר שאני יכול לשמור רק נתונים של אובייקט אחד? 05-12-02 12:02
 יהודה ברוך
#181

ז"א , אם יצרתי מספר אובייקטים עם המשתנים שלהם ואני מעוניין לשמור אותם בקובץ, אזי כל אחד מהאובייקטים ישמר בקובץ נפרד?
אם לא, הכיצד אוכל לטעון ערכים של אובייקטים שמורים מקובץ אחד עם מספר ערכים של אובייקטים שמורים?

תשובה: לא נכון.. ניתן לשמור נתונים של יותר מאובייקט אחד בקובץ אחד 05-12-02 14:01
 אלי חן (מנהל)
#184

אפשר לשמור את כל האובייקטים בקובץ אחד.

מן הסתם הכי קל יהיה אם כל אובייקט יישמר בשורה חדשה אחת, אבל ייתכן כי במחרוזת שמתקבלת מ-serialize יהיו ירידות שורה, לכן נצטרך לקודד את המחרוזת הזו למחרוזת אחרת שתהיה על גבי שורה אחת. לצורך העניין ניתן יהיה לקודד עם הפונקציות urlencode או base64_encode, ואלו יחזירו לנו מחרוזת של שורה אחת בדיוק.
כדי לשחזר את האובייקטים מן הקובץ, הכי קל יהיה לפתוח ולקרוא את הקובץ באמצעות הפונקציה file, שקוראת את הקובץ ומחזירה מערך שכל איבר בה היא שורה אחת מן הקובץ, ובמקרה שלנו כל שורה היא בעצם אובייקט מקודד. לפני שעושים unserialize למחרוזת, אז צריך לקודד בחזרה עם הפונקציה הנגדית: urldecode או base64_decode בהתאמה, ורק אחרי זה לעשות unserialize מהמחרוזת שנקבל.
שימוש בקידוד כזה יהיה גם יעיל מאוד אם רוצים להעביר אובייקטים דרך טופס (<FORM>), למשל.

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

לסיכום הפרק... 06-12-02 23:01
 יובל
#284

דבר ראשון, סוף סוף מצאתי לימוד OO מובן...
יפה!
דבר שני, מישהו משתמש בזה?
איך זה יכול לעזור ב PHP??

תשובה: עוזר... 07-12-02 00:00
 אלי חן (מנהל)
#286

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

למה יש ERROR? 08-12-02 02:01
 יואב פרברוב
#360

בהדגמה יש ERROR, למה?

רגע, שאלה 06-12-03 08:00
 alex9913
#904

בפונקציות רגילות בPHP
אם רוצים להשתמש במשתנים שנמצאים בעמוד צריך להוסיף לשורה הראשונה של הפונקציה את הביוטוי
GLOBAL
ולאחריו את כל המשתנים כדי ש"יראו" בתוך הפונקציה, במחלקות אין בעיות עם שימוש במשתנים שלא הועברו בפונקציה של המחלקה וגם לא מוגדרות במחלקה? "הגבלת ראיית המשתנים"
מקווה שהסברתי את עצמי ברור

משתנים גלובליים במתודות של מחלקה 06-12-03 09:02
 אלי חן (מנהל)
#913

בפונקציות רגילות, יש להגדיר משתנים גלובליים כגלובליים (global) כדי שיילקחו מבחוץ. באם משתנה לא מצויין כגלובלי אז הוא נחשב למשתנה מקומי של הפונקציה, וטווח ההגדרה שלו הוא רק בתוך הפונקציה.

בדיוק באותה הצורה, יש להגדיר משתנים גלובליים כגלובליים (global) במתודות של מחלקה כדי שיילקחו מבחוץ, אחרת הם נחשבים למשתנים מקומיים של המתודה וטווח הגדרתם הוא במתודה בלבד.
שימו לב שלא מגדירים משתני מחלקה כגלובליים בתוך מתודות של המחלקה.

איך עושים שזה ירד ויקרא שורה שורה 07-12-03 19:01
 נתנאל
#999

נגיד יש לי שני אובייקטים : $x1 x2
איך אני מכניס אותם לקובץ אחד שכל אחד בשורה נפרדת - ושזה יקרא כל אחד מהם כך?
(את הרעיון הבנתי - אבל לא את הביצוע)
כך שאם תצרף דוגמת קוד הכל יהיה ברור יותר
תודה מראש :) ויום נעים

השתמש בפונקציה file 08-12-03 05:00
 אלי חן (מנהל)
#1040

הפונקציה file קוראת את הקובץ לתוך מערך, כך שכל איבר במערך מייצג שורה בקובץ.. תוכל לעבור על המערך הזה ולעשות unserialize לאובייקטים ששמרת.

לא הבנתי... =[ 08-12-04 12:01
 איתן בןאב
#1753

לא הבנתי מה אתה מנסה להסביר פה.
ואת כל הפונקציות שלא הסברת עליהן....
בשני קבצים פתחת את object_info.dat שבעצם לא קיים כזה קובץ. (או לפחות לא הראת איפה יצרת אותו)
ועוד שאלה בfopen שבקובץ object_save.php הוספת אחרי הקובץ עוד משהוא (W+) מה זה ולמה צריך את זה ?

טעות בתשובה 3 במבחן 08-12-05 07:01
 עזריאל ברגר
#2610

המחשב מוציא לי פלט: of age.
והתשובה ה"נכונה" היא עם תגי B לפני ואחרי...


לדף הקודםקריאה לפונקציית הורה -הקודם
לתחילת הדףלתחילת הדף
הבא- בחן את עצמךלדף הבא