PHP 5.5.15 is released

Serialisierung von Objekten

Serialisierung von Objekten - Objekte in Sessions

serialize() erzeugt einen String, welcher die Byte-Stream-Repräsentation eines jeden Wertes besitzt, der in PHP gespeichert werden kann. unserialize() kann diesen String verwenden, um die ursprünglichen Variablenwerte wiederherzustellen. Verwendet man serialize(), um ein Objekt zu speichern, so werden alle Variablen dieses Objektes gespeichert. Die Methoden des Objektes werden nicht gespeichert, nur der Name der Klasse.

Damit man imstande ist, ein Objekt mit unserialize() wiederherzustellen, muss die Klasse des Objektes definiert sein. Das heißt, wenn man ein Objekt der Klasse A serialisiert, erhält man einen String, der sich auf die Klasse A bezieht und die Werte aller darin enthaltenen Variablen beinhaltet. Wenn man in einer anderen Datei diesen String wieder zu einem Objekt der Klasse A deserialisieren will, so muss die Klasse A in dieser Datei vorher bekannt sein. Dies kann man erreichen, indem man die Definition der Klasse A in eine mittels include ladbare Datei auslagert und diese Datei einbindet oder die Funktion spl_autoload_register() verwendet.

<?php
// classa.inc:

  
class {
      public 
$one 1;

      public function 
show_one() {
          echo 
$this->one;
      }
  }

// page1.php:

  
include("classa.inc");

  
$a = new A;
  
$s serialize($a);
  
// $s irgendwo ablegen, wo page2.php dies finden kann.
  
file_put_contents('store'$s);

// page2.php:

  // Dies ist nötig, damit unserialize korrekt funktioniert. 
  
include("classa.inc");

  
$s file_get_contents('store');
  
$a unserialize($s);

  
// Nun kann man die Funktion show_one() des Objektes $a
  // verwenden.
  
$a->show_one();
?>

Wenn eine Anwendung Sessions verwendet und die Funktion session_register() benutzt, um Objekte zu registrieren, so werden diese Objekte automatisch am Schluss jeder PHP-Seite serialisiert und in jeder nachfolgenden PHP-Seite deserialisiert. Das heißt, dass diese Objekte in jeder Seite der Anwendung auftauchen können, sobald diese Teil der Session werden. session_register() wurde in PHP 5.4.0 jedoch entfernt.

Es ist dringend empfohlen, dass wenn eine Anwendung Objekte zur späteren Verwendung in der Anwendung serialisiert, die Klassendefinitionen in der gesamten Anwendung eingebunden werden. Wird dies nicht beachtet, so wird das Objekt ohne eine Klassendefinition deserialisiert, was dazu führen wird, dass PHP dem Objekt eine Klasse __PHP_Incomplete_Class_Name zuweisen wird, welche keine Methoden besitzt. Dies wird das Objekt nutzlos machen.

Wenn also im obigen Beispiel $a Teil einer Session würde, indem man session_register("a") benutzt, so sollte die Datei classa.inc in jeder Seite eingebunden werden, nicht nur in page1.php und page2.php.

Beachten Sie neben den obigen Hinweisen dass man sich in die Serialisierungs- und Deserialisierungs-Ereignisse einklinken kann, indem man die Methoden __sleep() und __wakeup() eines Objektes verwendet. Die Verwendung von __sleep() erlaubt es nur eine Teilmenge der Eigenschaften eines Objektes zu serialisieren.

add a note add a note

User Contributed Notes 3 notes

up
38
php at lanar dot com dot au
4 years ago
Note that static members of an object are not serialized.
up
0
me at iabdullah dot info
3 hours ago
In case you're reading the official book that written by Rasmus and the other authors, Here is the serialization and unserialization Example (6-3) since it is written in the old fashion way (using session_register() ..) and has some typos.

(Log.php)
an object class, Log, provides two useful methods: write() to append a message to the logfile, and read() to fetch the current contents of the logfile. It uses __wakeup() to reopen the logfile and __sleep() to close the logfile.

<?php
class Log {
    private
$filename;
    private
$fh;

    public function
__construct ($fn)
    {
       
$this->filename = $fn;
       
$this->open();
    }

    public function
open ()
    {
       
$this->fh = fopen ($this->filename,'a') or die ("Can't open {$this->filename} !");
    }
    public function
write ($note)
    {
       
fwrite($this->fh, "{$note}\n");
    }
    public function
read ()
    {
        return
join ('', file($this->filename));
    }
    public function
__wakeup()
    {
       
$this->open();
    }
    public function
__sleep ()
    {
       
fclose ($this->fh);
        return array(
"filename");
    }
}
?>
Store the Log class definition in a file called Log.inc.

(front.php)
The front.php uses the Log class and PHP sessions to create a persistent log variable, $Logger.
<?php
include_once ("Serialization.php");
session_start();
?>
<html>
<head>
<title>Front Page</title>
</head>
<body>
<?php
$now
= strftime("%c");   

if (!isset(
$_SESSION['Logger']))
{
   
$l = new Log ("tmp/persistent_log");
   
$_SESSION['Logger'] = $l;
   
$l->write("Created {$now}");

    echo (
"<p> Created Session and Persistent Log File </p>");
}
else
{
   
$_SESSION['Logger']->write("Viewed Page 1 at {$now}");
    echo
"<p> The Log content : </p>";
    echo
nl2br($_SESSION['Logger']->read());
}
?>
<a href="next.php"> Move the next Page !!</a>
</body>
</html>

(next.php)
The file next.php shows , an HTML page, Following the link from the front page to this page triggers the loading of the persistent object $logger. The __wakeup() call reopens the logfile so the object is ready to be used.
<?php
include_once ("Serialization.php");
session_start();
?>
<html>
<head>
<title>Next Page</title>
</head>
<body>
<?php
$now
= strftime("%c");   
$logger = $_SESSION['Logger'];

$logger->write("Viewed Page 2 at {$now}");
echo
"<p> The Log content : </p>";
echo
nl2br($logger->read());
?>
</body>
</html>

Create folder 'tmp' and file 'persistent_log' to avoid getting fopen warning error message.
up
-23
wbcarts at juno dot com
4 years ago
PHP OBJECT SERIALIZATION

I use a database to store info rather than storing PHP Objects themselves. However, I find that having a PHP Object acting as an interface to my db is way useful. For example, suppose I have a TABLE called 'user' that looks like this.

CREATE TABLE user {
  user_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
  user_first VARCHAR(24) NOT NULL,
  user_last VARCHAR(24) NOT NULL,
  PRIMARY KEY (user_id)
);

Then I would create a PHP Class definition like so:

<?php

require('includes/db_connect.php');

class
User
{
  protected
$user_id;
  protected
$user_first;
  protected
$user_last;

  public function
__construct($id, $first, $last)
  {
   
$this->user_id = $id;
   
$this->user_first = $first;
   
$this->user_last = $last;
  }

 
# FUNCTIONS TO RETRIEVE INFO - DESERIALIZE.
 
public static function db_user_by_id($dbc, $id)
  {
   
$query = "SELECT * FROM user WHERE user_id=$id LIMIT 1";
    return
User::db_select($dbc, $query);
  }

  public static function
db_user_by_name($dbc, $first, $last)
  {
   
$query = "SELECT * FROM user WHERE user_first='$first' AND user_last='$last' LIMIT 1";
    return
User::db_select($dbc, $query);
  }

  protected static function
db_select($dbc, $query);
  {
   
$result = mysqli_query($dbc, $query);
    if(
mysqli_num_rows($result) > 0)
    {
     
$row = mysqli_fetch_array($result, MYSQLI_NUM);
      return new
User($row[0], $row[1], $row[2]);
    }
  }

 
# FUNCTIONS TO SAVE INFO - SERIALIZE.
 
public function insert($dbc)
  {
   
$query = "INSERT INTO user VALUES (NULL, '$this->user_first', '$this->user_last')";
   
$result = mysqli_query($dbc, $query);
  }

  public function
update($dbc)
  {
   
$query = "UPDATE user SET user_first='$this->user_first', user_last='$this->user_last' WHERE user_id=$this->id LIMIT 1";
   
$result = mysqli_query($dbc, $query);
  }

 
# GETTER and SETTER FUNCTIONS - DO NOT ALLOW SETTING OF ID
 
public function getId() {return $this->user_id;)
  public function
getFirst() {return $this->user_first;)
  public function
getLast() {return $this->user_last;)
  public function
setFirst($first) {$this->user_first = $first;}
  public function
setLast($last) {$this->user_last = $last;}

 
# CUSTOM FUNCTIONS
 
public function getFullName() {return $this->user_first . ' ' . $this->user_last;}
  public function
getLastFirst() {return $this->user_last . ', ' . $this->user_first;}
}

?>

Using PHP Objects for SERIALIZATION and DESERIALIZATION is now super-easy, for example:

<?php

require('User.php');

// INSERT a new user.
$user = new User(0, 'Frank', 'American');
$user->insert($dbc);  // done!

// UPDATE an existing user.
$user = User::db_user_by_id($dbc, 223);
$user->setFirst('Johnny');
$user->update($dbc);  // done!

mysqli_close($dbc);

?>
To Top