| 
   
   | 
    | 
  
   
    
Замечание: 
    In PHP 3, objects will lose their class association
    throughout the process of serialization and unserialization. 
    The resulting variable is of type object, but has no class
    and no methods, thus it is pretty useless (it has become
    just like an array with a funny syntax).
    
 | Предостережение |  
    The following information is valid for PHP >= 4 only. 
     |  
 
   serialize() returns a string containing a
   byte-stream representation of any value that can be stored in
   PHP. unserialize() can use this string to
   recreate the original variable values. Using serialize to
   save an object will save all variables in an object.  The
   functions in an object will not be saved, only the name of
   the class.
   
   In order to be able to unserialize() an object, the
   class of that object needs to be defined. That is, if you have an object
   $a of class A on page1.php and serialize this, you'll
   get a string that refers to class A and contains all values of variabled
   contained in $a. If you want to be able to unserialize
   this on page2.php, recreating $a of class A, the
   definition of class A must be present in page2.php. This can be done for
   example by storing the class definition of class A in an include file and
   including this file in both page1.php and page2.php.
   
   If you are using sessions and use session_register()
   to register objects, these objects are serialized automatically
   at the end of each PHP page, and are unserialized automatically on
   each of the following pages. This basically means that these objects
   can show up on any of your pages once they become part of your
   session.
   
   It is strongly recommended that you include the class
   definitions of all such registered objects on all of your
   pages, even if you do not actually use these classes on all
   of your pages. If you don't and an object is being
   unserialized without its class definition being present, it
   will lose its class association and become an object of class
   stdClass without any functions available
   at all, that is, it will become quite useless.
   
   So if in the example above $a became part of a session
   by running session_register("a"), you should include the
   file classa.inc on all of your pages, not only page1.php
   and page2.php.
   
  
 
  Serializing objects - objects in sessions
  
 
 
  zabmilenko at hotmail dot com
  10-Mar-2006 05:20
  
This was something that surprised me when I was testing serialization tonight.  Consider the following code: 
 
<?php 
 
class Test1 { protected $key = 'value'; } 
class Test2 { private   $key = 'value'; } 
class Test3 { public    $key = 'value'; } 
 
$t1 = new Test1; 
$t2 = new Test2; 
$t3 = new Test3; 
 
echo "<pre>"; 
echo "Protected Size: " . strlen(serialize($t1)) . "\n"; 
echo "Private Size:   " . strlen(serialize($t2)) . "\n"; 
echo "Public Size:    " . strlen(serialize($t3)) . "\n"; 
echo "</pre>"; 
 
?> 
 
When I executed this code on my PHP 5.1.2/WinXPHsp1/Apache2 setup, the result was the following: 
 
<?php 
 
Protected Size: 41 
Private Size:   46 
Public Size:    38 
 
?> 
 
It may be useful for you to take it into consideration, just in case.
 
   
  
 
 
  tatwane at hotmail dot com
  08-Mar-2006 11:35
  
if you are using many fields in your database and want to reduce the number of requests to speed up database access, a good idea is to use objects instead of tables, to serialize them and store them into an unique field with an id and then to retrieve them and unserialize them 
 
this could also make your database more simple when using many fields
 
   
  
 
 
  maurits_dekkers at DONTSPAM_ME dot planet dot nl
  19-Dec-2005 04:35
  
If you have register_globals = on, then be very careful about naming conventions when it comes to sessions and objects. 
 
Example: 
 
<?php 
 
session_start() 
$_SESSION["order"] = "SomeValue"; 
 
$order = new Classname; 
 
?> 
 
This will activate the __PHP_Incomplete_class object within your session variable! This, all references and methods to $order will not work. 
 
Took me hours to figure this out, so I hope this is helpful.
 
   
  
 
 
  fluw at gmx dot net
  13-Aug-2005 09:06
  
never serialize an object, if it contains references to itself. Just create the object in an array, or make a reference of this object in an array before calling serialize() and serialize the array instead of the object. 
 
print_r is fine to validate a reference: The reference will be serialized in a right way, if print_r returns a *recursive* on right place (look carefully). 
 
Just have a look on this small example: 
 
<? 
    class foo { 
        var $bar; 
         
        function addBar() { 
            $this->bar = new bar(&$this); 
        } 
    } 
     
    class bar { 
        var $parentFoo; 
         
        function bar(&$partentBean) { 
            $this->parentFoo =& $partentBean; 
        } 
    } 
     
    $foo = new foo(); 
    $foo->addBar(); 
     
    $fooArray = array(&$foo); 
     
    echo "<pre>"; 
        print_r($foo); 
        echo serialize($foo); 
    echo "</pre>"; 
     
        echo "<pre>"; 
        print_r($fooArray); 
        echo serialize($fooArray); 
    echo "</pre>"; 
     
?> 
 
OutPut: 
 
foo Object 
( 
    [bar] => bar Object 
        ( 
            [parentFoo] => foo Object 
                ( 
                    [bar] =>  *RECURSION* 
                ) 
 
        ) 
 
) 
O:3:"foo":1:{s:3:"bar";O:3:"bar":1:{s:9:"parentFoo";O:3:"foo":1: 
{s:3:"bar";O:3:"bar":1:{s:9:"parentFoo";R:3;}}}} //sorry for linebreak 
 
Array 
( 
    [0] => foo Object 
        ( 
            [bar] => bar Object 
                ( 
                    [parentFoo] =>  *RECURSION* 
                ) 
 
        ) 
 
) 
a:1:{i:0;O:3:"foo":1:{s:3:"bar";O:3:"bar":1:{s:9:"parentFoo";R:2;}}} 
 
if you serialize the object, the the refernce becomes a copy an first the reference inside the copy is a real reference, (but just only to the copy, for sure :).
 
   
  
 
 
  nate at NO-SPAMnatereed dot com
  25-May-2005 09:31
  
I can't store an instance of MySQLPagedResultSet (I grabbed this code from Kevin Yank at Sitepoint) in my session without losing all the data.  This seems related to the previous post since the result set member variable is from calling mysql_query().  It doesn't get serialized properly and when I retrieve it from the session the result set is empty. 
 
My workaround is store the query (ie. select * from mydata where id in (1,2,3...)) instead of the result set.  In this particular case, it works beautifully and yields a big performance boost, since the id's are generated from several other queries that can now be avoided.  With query caching on in mysql, I would not be surprised if this is just as fast or faster than retrieving the result set from the session.  There are fewer potential data synchronization problems, too, since the info from mydata is fresh.
 
   
  
 
 
  kendlj at NOSPAM dot web dot de
  21-Apr-2005 05:51
  
Was wondering, if References are also lost after serializing and deserializing in php5. 
 
Wrote a testfile and my result is: 
All references are restored corretly. Even if the classes where recursively referenced. 
 
Here is the code of the file: 
 
<? 
class A 
{ 
    public $a_var; 
    public $parent; 
     
    public function __construct($parent) 
    { 
        $this->parent=$parent; 
    } 
} 
 
class B 
{ 
    public $Ref_auf_A; 
    public $aObj; 
     
    public $name=""; 
     
    public function __construct($InhaltA) 
    { 
        $this->aObj=new A($this); 
        $this->aObj->a_var=$InhaltA; 
         
        $this->Ref_auf_A=$this->aObj; 
    } 
} 
 
$B_obj = new B("Inhalt von A"); 
$B_obj->name="My is <defaultName>"; 
 
echo "Object B before serializing:<pre>"; 
print_r($B_obj); 
echo "</pre><br><br>"; 
 
$serB=serialize($B_obj); 
echo "Object B serialized: ".$serB."<br><br>"; 
 
$B_obj = unserialize($serB); 
echo "Object B deserializedt:<pre>"; 
print_r($B_obj); 
echo "</pre><br><br>"; 
 
$B_obj->Ref_auf_A->a_var="Test"; 
echo "Object A reference content changed, should have changed everywhere:<pre>"; 
print_r($B_obj); 
echo "</pre><br><br>"; 
 
$B_obj->Ref_auf_A->parent->name="My name changed"; 
 
echo $B_obj->name; 
 
?>
 
   
  
 
 
  fdreger at amiga dot pl
  19-Mar-2005 05:43
  
It seems that serializing an object dereferences all its attributes that were references - even if the object they referenced was contained within the serialized one. 
Consider this example: 
 
<? 
class foo { 
  var $a=new array(); 
}  
 
$example=new foo; 
$obj=new whatever(); 
$example->a[]=&$obj; 
$example->a[]=$obj; 
 
$string=serialize(example); 
$example=unserialize(string); 
 
?>
 
   
  
 
 
  evan dot php dot net at timewarp dot org
  03-Jun-2004 03:45
  
A special gotcha for unserializing stored objects.  If you alter the class (adding new methods), they will appear and be available when the object is unserialized.  If, however, you alter the parent class that the class extends, the methods are *not* available, and any renamed ones silently vanish (the method disappears and does not reappear under the new name). 
 
A way to get around this is to create a new dummy method in the child class and rename it each time you alter the parent class.  This is very much a Bad Solution when you have to deal with a base class that is extended by dozens of other classes.  Especially when you have a database full of serialized objects, each of which is a child of the base class.  There appears to be no runtime fix. 
 
Applies to PHP 4.  Not sure about 5.
 
   
  
 
 
  markg at byu dot edu
  05-May-2004 04:32
  
When working with a installation where Register Globals if off.  You must remeber to use $_SESSION['objectName'] to  store objects that will be used on multiple pages. 
 
To re-use a saved object, you must define your object (i.e. include it's class file) before you call session_start(), or the object becomes unusable.
 
   
  
 
 
  arthurp at nospam free dot fr
  21-Nov-2003 01:00
  
Good news when serializing a class and then reading it back into the similar or modified class. 
PHP behaves very well when a class was serialized and then it is unserialized to initialize similar class or when the class was modified meanwhile. 
 
Try this sample:  
First version of the class A contains members $one and $three. An instance of this class is stored into the file. 
 
The second version of the class A contains members $one as in prevoius but it also contains $two and and it doesn't contain $three member. The file is read back. 
Resulting class is still working ! 
 
<?php 
class A  
{ 
    var $one = 1; 
    var $three = 3; 
    function show_one(){ echo $this->one."<br>";} 
} 
 
class A  
{ 
    var $two = 2; 
    var $one = 1; 
 
    function show_one(){ echo $this->one."<br>"; } 
    function show_two(){ echo $this->two."<br>"; } 
} 
 
include("classa.inc"); 
 
$a = new A; 
$s = serialize($a); 
$fp = fopen("savedclass.tmp", "w"); 
fputs($fp, $s); 
fclose($fp); 
 
$a->show_one(); 
var_dump($a); 
 
include("classa_modified.inc"); 
 
$s = implode("", @file("savedclass.tmp")); 
$a = unserialize($s); 
 
$a->show_one(); 
$a->show_two(); 
var_dump($a); 
?> 
 
Resulting Output: 
1 
2 
object(a)(3) { ["two"]=> int(2) ["one"]=> int(1) ["three"]=> int(3) } ?> 
 
Note: 
- $one member is unserialized normally 
- $two member exist after unserialisation and it's well initialised with value 2 
- show_two() function is working after unserialization 
- $thee member exist was loaded too even if it isn't declared in modified version of the class !
 
   
  
 
 
  okoro22 at yahoo dot com
  04-Mar-2003 05:21
  
I had a problem using session_register() to globally store a class that I was working with. I hope my solution will help beginners understand this concept of sessions in PHP  
 
When you use session_register() to store any object, yes you don't need to call session_start() unless you want to. However in other pages where you want to use that object, you must call session_start() after you have included the class definition of the file. Failure to do this will unserlize your object without its functions and it will be pretty useless. 
 
Hope it helps someone. 
 
Cheers.
 
   
  
 
 
  dan at binaryfrost dot net
  15-Nov-2002 10:10
  
Serialization is very useful for the storing of objects in databases. 
The following example stores an obbect in a mySQL db: 
 
# Seperate Class. 
include 'thisObjectClass.php'; 
 
# Create instance of a class. 
$object = new thisObjectClass; 
 
# Create link to the database 
$link = mysql_connect('host', 'user', 'password'); 
mysql_select_db('dbname', $link); 
 
# Formulate query and submit. 
$sql_query = mysql_query("INSERT INTO objecttable(object) VALUES (serialize($object)") or print (mysql_error()); 
 
# Retrieve blob object. 
$sql_query = mysql_query("SELECT object FROM objecttable WHERE 1) or print (mysql_error()); 
$row = mysql_fetch_row($sql_query); 
 
# This should show string / text data. 
print $row[0]; 
 
# This should show 'object'. 
print unserialize($row[0])."<br>"; 
 
# Close db link. 
mysql_close($link);
 
   
  
 
 
  michael at nospam dot dynamine dot net
  14-Nov-2002 09:07
  
Don't forget to lock your storage file using flock() before opening the file you wish to use to store your serialized object(s)!    PHP will make no attempt to prevent two threads or processes from writing to your file at the same time and you can easily end up with a corrupted data store unless you serialize access to your storage.  (Note that using NFS for your storage may not be lock-safe.)
 
   
  
 
 
  evan at unixpimps dot org
  24-Aug-2002 11:26
  
A quick note about objects containing another object as a variable. Say you have something like this: 
 
class A { 
var $A_Var; 
} 
 
class B { 
var $A 
var $B_Var; 
function B() { 
$this->A = new A(); 
} 
} 
 
$B = new B(); 
$B->A->A_Var = "A_Var value"; 
 
--- 
 
When you try to serialize() an instance of B() $B->A->A_Var doesn't seem to keep it's value. 
 
After much fighting with this the solution I found was to append to my __sleep and __wakeup functions and serialize $this->A in __sleep and then unserialize it in __wakeup.  
 
class A { 
var $A_Var; 
} 
 
class B { 
var $A 
var $A_serialized; 
var $B_Var; 
function B() { 
$this->A = new A(); 
} 
 
function __sleep() { 
$this->A_serialized = serialize($this->A); 
return array('A_serialized', 'B_Var'); 
} 
function __wakeup() { 
$this->A = unserialize($this->A_serialized); 
} 
}
 
   
  
 
 
  felizk at hotmail dot com
  08-Jul-2002 12:31
  
Got around the session_auto_start problem by using: 
 
session_write_close(); 
class defination 
session_start(); 
 
works for me
 
   
  
 
 
  I hate spam
  08-Jul-2002 12:57
  
The deserialize callback function is pretty useless if you name your classes and files using title case (ie ClassName.php), because PHP changes all classnames to lower case!!!
 
   
  
 
 
  ndp9 at yahoo dot com
  26-May-2002 05:13
  
In case this isn't clear: 
In 4.2 and below: session.auto_start and session objects are mutually exclusive.
 
   
  
 
 
  hhuggins at fedex dot com
  17-Apr-2002 01:52
  
The problem with objects during session management arise because the object definition must exist before starting the session.  i.e. if you have object x and you want to use it in a session, you have to perform the following. 
 
<? 
 
class x 
{ 
...definition here 
} 
 
session_start(); 
session_register("x_as_variable"); 
 
?> 
 
if object x is defined in another file, make sure that the file is included or required BEFORE you start the session. 
 
<? 
require("x.inc"); 
 
session_start(); 
session_register("x_as_variable"); 
?> 
 
This stops the INCOMPLETE_OBJECT response eliminating the need to create an array representation for an object.
 
   
  
 
 
  ggiulb at netscape dot net
  17-Mar-2002 07:00
  
PHP.INI FILE AND SESSION.AUTO_START 
 
Set 
 
session.auto_start = 0 
 
in php.ini file if you want that all works well during serialization/unserialization.  
 
If session.auto_start is set to 1 all class definition is loaded after unserialization process, infact you obtain a messagge error  like this "The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition className of the object you are trying to operate on was loaded _before_ the session was started in scriptFile on line n"
 
   
  
 
 
  grant_mjtr at hotmail dot com
  20-Feb-2002 01:15
  
A quick note about automatic serialisation in sessions. 
 
If you have an object  
$myCart = new ShoppingCart();   
 
and this object contains variables which are objects 
function ShoppingCart() 
{ 
    $mySingleItem = new BasketItem(); 
} 
this will work fine and you can access the contained object $mySingleItem and its methods etc ONLY WHILE YOU ARE ON THE PAGE WHERE YOU CREATED IT. 
 
if you are using sessions and register the cart 
session_register('myCart') 
 
the ShoppingCart object is serialised and unserialised on the next page ok but the inner BasketItem object is just garbled. 
 
The only solution I have found is to use an array in the ShoppingCart instead of an object.  What a pain!
 
   
  
 
 
  william at scriptingbiz dot com
  22-Sep-2001 05:03
  
When storing an object that was generated with:
 
 
 $row = mysql_fetch_object($result)
 
 
there is no apearent way to define the class of that object in the next page, without querying the database, and fetching a row as an object.  This needs to be done so any such objects can be restored (deserialized) from a PHP4 Session.  
 
 
It needs to be done before session_start() or session_register().
 
   
  
  
 |    |