PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

settype> <print_r
Last updated: Fri, 09 May 2008

view this page in

serialize

(PHP 4, PHP 5, PECL axis2:0.1.0-0.1.1)

serialize — Generates a storable representation of a value

Description

string serialize ( mixed $value )

Generates a storable representation of a value

This is useful for storing or passing PHP values around without losing their type and structure.

To make the serialized string into a PHP value again, use unserialize().

Parameters

value

The value to be serialized. serialize() handles all types, except the resource-type. You can even serialize() arrays that contain references to itself. Circular references inside the array/object you are serialize()ing will also be stored. Any other reference will be lost.

When serializing objects, PHP will attempt to call the member function __sleep prior to serialization. This is to allow the object to do any last minute clean-up, etc. prior to being serialized. Likewise, when the object is restored using unserialize() the __wakeup member function is called.

Return Values

Returns a string containing a byte-stream representation of value that can be stored anywhere.

Examples

Example #1 serialize() example

<?php
// $session_data contains a multi-dimensional array with session
// information for the current user.  We use serialize() to store
// it in a database at the end of the request.

$conn odbc_connect("webdb""php""chicken");
$stmt odbc_prepare($conn,
      
"UPDATE sessions SET data = ? WHERE id = ?");
$sqldata = array (serialize($session_data), $_SERVER['PHP_AUTH_USER']);
if (!
odbc_execute($stmt, &$sqldata)) {
    
$stmt odbc_prepare($conn,
     
"INSERT INTO sessions (id, data) VALUES(?, ?)");
    if (!
odbc_execute($stmt, &$sqldata)) {
        
/* Something went wrong.. */
    
}
}
?>

ChangeLog

Version Description
4.0.7 The object serialization process was fixed.
4.0.0 When serializing an object, methods are not lost anymore. Please see the Serializing Objects for more information.

Notes

Note: It is not possible to serialize PHP built-in objects.



settype> <print_r
Last updated: Fri, 09 May 2008
 
add a note add a note User Contributed Notes
serialize
Aditya P Bhatt (adityabhai at gmail dot com)
31-Mar-2008 01:29
Here is a simple code to understand serialize function:

<?php
class dog {

    var
$name;
    var
$age;
    var
$owner;

    function
dog($in_name="unnamed",$in_age="0",$in_owner="unknown") {
       
$this->name = $in_name;
       
$this->age = $in_age;
       
$this->owner = $in_owner;
    }

    function
getage() {
        return (
$this->age * 365);
    }
   
    function
getowner() {
        return (
$this->owner);
    }
   
    function
getname() {
        return (
$this->name);
    }
}
?>

<body bgcolor=white>
<h1>Beware the dog</h1>
<?php
$ourfirstdog
= new dog("Rover",12,"Lisa and Graham");
$dogdisc = serialize($ourfirstdog);
 
$pet = unserialize($dogdisc);
$old = $pet->getage();
$name = $pet->getname();
print
"Our first dog is called $name and is $old days old<br>";
print
$dogdisc;
?>
Marek Soldt
21-Nov-2007 06:50
serialize() and unserialize() behave a bit crazy if you try to work with bigger strings (100kb of size). It helps to divide the string parts to array:

<?php
// string in $data
               
$ko = 4096;
               
$data2 = array();
                for(
$i=0;$i<ceil(strlen($data) / $ko);$i++) {
                 
$data2[] = substr($data,($i * $ko),(($i+1) * $ko));
                }
// prepared array in $data2
?>

...before serialize()

and

<?php
// array in $data2
             
$data = '';
              for(
$i=0;$i<count($data2);$i++) {
               
$data .= $data2[$i];
              }
// your string in $data
?>

...after unserialize()
Feral
16-Nov-2007 04:30
While it may not be recommended, it is possible to convert an object to another class while conserving all of its properties (public, protected and private), using serialize.

<?php
function cast_class($object, $newclass)
{
    if( !
is_object($object) )
    {
       
trigger_error('cast_class expects parameter 1 to be object, ' . gettype($object) . ' given', E_USER_WARNING);
        return
false;
    }
    if( !
class_exists($newclass) )
    {
       
// We'll save unserialize the work of triggering an error if the class does not exist
       
trigger_error('Class ' . $newclass . ' not found', E_USER_ERROR);
        return
false;
    }
   
$serialized_parts = explode(':', serialize($object));
   
$serialized_parts[1] = strlen($newclass);
   
$serialized_parts[2] = '"' . $newclass . '"';
    return
unserialize(implode(':', $serialized_parts));
}

?>

Please note that several built-in classes (or classes that are declared in PECL extensions) will not behave as PHP-declared classes and will ne be able to be serialized properly. Because of that, you will not be able to change their class using this function.

Please also note that serialize and unserialize are memory-hungry functions.
barbuj at NOSPAM dot yahoo dot com
14-Nov-2007 11:19
In my specific situation, I wanted to be able to pass some data from page to page, but without relying on a session variable. The answer I came up with was to serialize() the object in question, pass it on to the next page as a hidden form field, then unserialize() it. When ALL class variables are public, this worked fine. However, if there was at least one private/protected variable, the code no longer worked as expected ("Fatal error: Call to a member function display() on a non-object in page2.php on line 4")

As others have already mentioned, private/protected class variables will not behave nicely (private variables are prefixed by class_name + &#65533;, while protected variables are only prefixed by &#65533; - when looking at the page source using Firefox). Internet Explorer does NOT display the extra character between the class name and variable name, but the code still doesn't work as one would expect.

Suppose you have a simple class:

testclass.php
=============
<?php
class TestClass {
  var
$i = 1;

  function
display() {
    echo
"i=" . $this->i;
  }
?>

page1.php
=========
<?php
 
require_once 'testclass.php';
 
$tc = new TestClass;
 
$tc->display();
?>
<form method = "post" action = "page2.php">
<input type = "hidden" name = "str" value = "<?php echo htmlspecialchars( serialize( $tc ) ); ?>">
<input type = "submit">
</form>

page2.php
=========
<?php
 
require_once 'testclass.php';
 
$tc = unserialize( stripslashes( htmlspecialchars_decode( $_POST["str"] ) ) );
 
$tc->display();
?>

The fix, suggested by evulish on #php/irc.dal.net, is to replace htmlspecialchars()/htmlspecialchars_decode() by base64_encode()/base64_decode. The code becomes:

page1.php
=========
<input type = "hidden" name = "str" value = "<?php echo base64_encode( serialize( $tc ) ); ?>">

page2.php
=========
<?php
  $tc
= unserialize( base64_decode( $_POST["str"] ) );
?>

Hope this will help someone...
Jeex
06-Nov-2007 11:59
It may be worth noting that, depending on the size of the object you are serializing, the serialize function can take up a lot of memory.

If your script isn't working as expected, your serialize call may have pushed the memory usage over the limit set by memory_limit in php.ini.

More info on memory limits here: http://www.php.net/manual/en/ini.core.php
aaron dot krohn at gmail dot com
13-Sep-2007 05:45
@ nothanks

you should be able to prevent your serialized array from breaking the query by escaping it.

$nested_array = serialize($array);
$query_safe = mysql_real_escape_string($nested_array);
aksel at metal dot ee
13-Sep-2007 12:31
To serialize objects with fields that contain unicode values use that logic.

Note! Obviously it does not convert correctly possible unicode values in arrays that may be member values of the object. Use an array class for that that inherits from the same base object that implements that serialization;)

<?php
/**
                  * Serializes object with/without unicode fields
                  * Before serializing encodes unicode values
                  *
                  * @return string
                  */
                 
public function serialize(){
                      
$serialized = array();
                       foreach(
array_keys(get_class_vars(get_class($this))) as $key){
                           if(
is_array($this->$key) ){
                               eval(
'$serialized["'.$key.'"] = serialize($this->'.$key.');');
                           }else{
                                eval(
'$serialized["'.$key.'"] = utf8_encode($this->'.$key.');');
                           }
                       }
                      
$str = serialize($serialized);
                       return
$str;
                  }
                 
/**
                   * Unserializes object with/without unicode fields
                   *
                   * @param string Serialized data
                   */
                  
public function unserialize($serialized){
                      
$data = unserialize($serialized);
                       foreach(
$data as $prop => $val){
                           if(
is_array($this->$prop) ){
                               
$this->$prop = unserialize($val);
                           }else{
                               
$this->$prop = utf8_decode($val);
                           }
                       }
                   }
?>
nothanks at nothanks dot no
17-Aug-2007 12:02
I had to put a massive multidimensional array in a single field in the database. Unfortunatly the array contained lots of "forbidden" characters: ", ', ;, :, and so on and so forth, breaking the query and my later attempts at deserialize().

Here's a quick and dirty solution:
<?php
$safe_string_to_store
= base64_encode( serialize( $multidimensional_array ) ) ;
?>

And in the other end:
<?php
$encoded_serialized_string
= dbh->query("SELECT archives_arr FROM ". $table_name . " WHERE id=0")

$array_restored_from_db = unserialize( base64_decode( $encoded_serialized_string ));
?>
deminy at deminy dot net
08-Aug-2007 06:44
Reply to erudd's post:

The regular expression you used to unserialize a PHP session file won't work if the session file contains string variable which contains character "|".

As I can see now, there is no any regular expression that can easily split data in a PHP session file. To read data from a session file, we may have to write a function to read content from the file, and then parse the content.
btbeat at gmail dot com
28-Jun-2007 10:09
Generally when I do an insert into a database table of posted data, I use the recommended mysql_real_escape_string function, with stripslashes if the get_magic_quotes_gpc is on.
<?php
function prepData($var) {
  if (
get_magic_quotes_gpc()) {
   
$var = stripslashes($var);
  }
return
mysql_real_escape_string($var);
}
?>
I've been having a problem inserting a serialized array into a MySQL database that contained single and double quotes for values.

ex: "quotes" => "some 'quoted' "text""
you'd think it would be:
a:1:{s:6:"quotes";s:20:"some 'quoted' "text"";}
as prepData function would strip the slashes.

However, what goes into the database is:
a:1:{s:6:"quotes";s:24:"some 'quoted' "text"";}
as if there are slashes before the single and double quotes.

Obviously on unserializing the data, there is an error, as 24 chars are expected, when there are only 20.

So, the solution I've coded for my safe insert prepData function is:
<?php
function prepData($var, $serialized = 0) {
  if(
$serialized == 0 )  {
    if (
get_magic_quotes_gpc()) {
     
$var = stripslashes($var);
    }
  }
return
mysql_real_escape_string($var);
}
?>

when inserting plain data from a post:
<? $data = prepData($data); ?>

for serialized data:
<? $data = prepData($data, 1); ?>

cracked my head on this one a bit :|

strange behaviour for serialize(), i.e. string count, counts slashes that are not there.
friday13 at ig dot com dot br
19-Jun-2007 04:15
I have problem to use serialize function with hidden form field and the resolution was use htmlentities.

Ex.:

<?

$lista
= array( 'pera', 'maça', 'laranja' );

print
"< input type='hidden' name='teste' value='htmlentities( serialize( $lista ) )'" >";

?>
lacent at gmail dot com
13-Jun-2007 07:22
i noticed the same problem related to quotes, but the person below had no code detailing it. i can only assume he wrote it to fix values, and not to fix the whole array, so heres 2 functions to handle encoding the array.

    function slw_serial ( $var = array(), $recur = FALSE )
    {
        if ( $recur ) {
            foreach ( $var as $k => $v )
            {
                if ( is_array($v) ) {
                    $var[$k] = slw_serial($v, 1);
                } else {
                    $var[$k] = base64_encode($v);
                }
            }
            return $var;
        } else {
            return serialize(slw_serial($var, 1));
        }
    }
       
    function slw_unserial ( $var = FALSE, $recur = FALSE )
    {
        if ( $recur ) {
            foreach ( $var as $k => $v )
            {
                if ( is_array($v) ) {
                    $var[$k] = slw_unserial($v, 1);
                } else {
                    $var[$k] = base64_decode($v);
                }
            }
            return $var;
        } else {
            return slw_unserial(unserialize($var), 1);
        }
    }

---------
USAGE:
---------

    $array = array();
    $array[] = 'this "is a" test';
    $array[] = array('pos'=>'test', 'name'=>'some "dude in" cali');
    $array = slw_serial($array);
    echo $array . '<Br><br>';
    $array = slw_unserial($array);
    echo print_r($array, 1);
kris dover
22-Apr-2007 02:45
The PHPSerialization class linked in my last comment now supports serialize()'ing java objects to the php serialization text format, thus facilitating a means of data inter-change between php and java communicating against a common php serialized data source.

reverse mappings are as follows:
   _PHP Type_   <-----------------   _Java Type_
      array                            java.lang.Object[]
      int                                java.lang.Byte
      int                                java.lang.Short
      double                           java.lang.Float
      double                           java.lang.Long
      double                           java.lang.BigInteger
      double                           java.lang.BigDecimal
      string                            java.lang.Character
      string                            java.lang.CharBuffer
      string                            java.lang.StringBuffer
krisdover at hotmail dot com
11-Apr-2007 11:11
For anyone looking for a way to import PHP serialized variables into java as java Objects; I have written a simple class to unserialize strings containing PHP serialized variables. It makes the follow type mappings:

  _PHP_Type_   --------->   _Java_Object_Type_
     array                            java.util.HashMap
     int                                java.lang.Integer
     double                           java.lang.Double
     boolean                         java.lang.Boolean
     string                            java.lang.String

and it does not presently support the PHP Object type.

Download the source code here: http://lappy.gotdns.com/drupal/files/PHPSerialization.java

Regards
admin at goodsoft dot lv
19-Nov-2006 05:25
When I serialized an object and looked into resulting string, I mentioned that all private properties' names were prefixed by class name.

This code:
<?php
       
class myclass {
                private
$priv1 = "val1",
                          
$myclasspriv2 = "val2";
                public
$pub = "val3";
        }

       
$inst = new myclass ();
        echo
serialize($inst);
?>
resulted in (don't look at word wrapping):
O:7:"myclass":3:{s:14:"myclasspriv1";
s:4:"val1";s:21:"myclassmyclasspriv2";
s:4:"val2";s:3:"pub";s:4:"val3";}
Ates Goral
18-Jul-2006 08:59
Corrections/clarifications to  "Anatomy of a serialize()'ed value":

All strings appear inside quotes. This applies to string values, object class names and array key names. For example:

s:3:"foo"
O:7:"MyClass":1:{...
a:2:{s:3:"bar";i:42;...

Object property names and values are delimited by semi-colons, not colons. For example:

O:7:"MyClass":2:{s:3:"foo";i:10;s:3:"bar";i:20}

Double/float values are represented as:

d:0.23241446
egingell at sisna dot com
16-May-2006 02:12
<?
/*
Anatomy of a serialize()'ed value:

 String
 s:size:value;

 Integer
 i:value;

 Boolean
 b:value; (does not store "true" or "false", does store '1' or '0')

 Null
 N;

 Array
 a:size:{key definition;value definition;(repeated per element)}

 Object
 O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}

 String values are always in double quotes
 Array keys are always integers or strings
    "null => 'value'" equates to 's:0:"";s:5:"value";',
    "true => 'value'" equates to 'i:1;s:5:"value";',
    "false => 'value'" equates to 'i:0;s:5:"value";',
    "array(whatever the contents) => 'value'" equates to an "illegal offset type" warning because you can't use an
    array as a key; however, if you use a variable containing an array as a key, it will equate to 's:5:"Array";s:5:"value";',
     and
    attempting to use an object as a key will result in the same behavior as using an array will.
*/
?>
erudd at netfor dot com
30-Mar-2006 11:36
To unserialize a PHP session file, unserlize can not be used directly.
The data must be split, as the php session file also contains the names of the variables which serialize/unserialize do not do.  Here is a simple preg_split that will acomplish the split.. (regex not thuroughly tested, but should work for most all circumstances)

<?php
$session
= file_get_contents($session_file);
$data = preg_split('/([A-Za-z_][A-Za-z0-9_]*)\|/',$session,-1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
?>

$data[0] will contain the variable name, and $data[1] will contain the serialized data.  so in effect
<?php
$$data[0] = unserialize($data[1]);
?>
will restore that one variable.

just go through the $data array evens being the variable name, odd being the data.  You can use this to create a simple command line session viewer:)
me-no-spam-iain at iaindooley dot com
11-Mar-2006 03:26
i've just been having fun with the Serializable interface. The big prob is that get_class_vars does not return the current values of the vars, and get_object_vars does not return private members :-( this behaviour was alledgedly fixed in cvs march 2005, but is back again!! i've reported it here:

http://bugs.php.net/bug.php?id=36693

the following are serialize and unserialize functions that will allow you to implement the Serializable interface, saving all members' current values and giving any extending classes the opportunity to add in any of their private member variables as well.

        public function serialize()
        {
            $serialized = array();

            foreach(array_keys(get_class_vars(__CLASS__)) as $key)
                eval('$serialized[\''.$key.'\'] = $this->'.$key.';');
            $this->serializeMore($serialized);
            return serialize($serialized);
        }

        protected function serializeMore(&$arr)
        {
        }

        public function unserialize($serialized)
        {
            $data = unserialize($serialized);

            foreach($data as $prop => $val)
                $this->$prop = $val;
            $this->unserializeMore($data);
            $this->releaseTable();

            return true;
        }

        protected function unserializeMore($data)
        {
        }
angel at support-24 dot com
09-Feb-2006 09:25
I recently had a problem inserting serialized array in mysql DB using PEAR DB_Base class functions. mySQL fails to insert the serialized array because the serialized data contains semicolon. A way to solve that problem is to make same changes to the serialized data:

$serializeorder = serialize($order);
$serializeorder = preg_replace("#;#msi",'0x3B',$serializeorder);
$serializeorder = preg_replace("/(\n)|(\r)/"," ",$serializeorder);
$serializeorder = addcslashes($serializeorder, "\0..\37!@\@\177..\377");
$serializeorder = addslashes($serializeorder);

Here we substitute the semicolon with it's hex. We alse get rid of cariage return. Remember to make the vise versa substitution again when extracting the data.
Neil Green
03-Feb-2006 02:23
Are you trying to store and retrieve an object from session and it's disappearing?  Did you look at what the serialized object looked like and saw a strange "N;"?  Does the object you're trying to serialize or store in a session define the __call magic method?

Here's the problem:  If you try to serialize an object that uses the __call magic method you are not going to be able to unserialize it.

Here's what happens:

1.  You try to serialize an object with the __call magic method defined
2.  The magic method __sleep is always called on an object being serialized
3.  __call traps __sleep because it's not defined
4.  __call does not respond to __sleep with what is expected: an array of properties to serialize

The solution is defining a __sleep method that returns what it's supposed to when you define a __call:

<?
// This is just a handy debug function
function show( $object ){ echo "<pre>" . print_r( $object, true ) . "</pre>"; }

class
foo
{
    private
$private = "private value";
    public
$public = "public value";
   
    public function
__call( $method, $arguments )
    {
       
    }
   
   
// Remove this and serialise/unserialse won't work
   
public function __sleep()
    {
        return
array_keys( get_object_vars( $this ) );
    }
}

$foo = new Foo();

show( $foo );

$serializedFoo = serialize( $foo );
show( $serializedFoo );
show( unserialize( $serializedFoo ) );
?>

BTW, I'm using PHP Version 5.0.4 on Windows.

To the editor:  This post may be useful under the __call, __unserialise, and session pages as well.
Embeded nulls with private vars
18-Jan-2006 05:08
If you are serializing an object with private variables, beware. The serialize() function returns a string with null (\x00) characters embedded within it, which you have to escape. Not great if you're trying to save objects into a DB...
16-Jan-2006 04:47
I use PHP 4.3.10 and I found out that if you use a class "MyClass", the constructor of the class must be called "__construct()" and NOT "MyClass()" like in Java or other languages.

If you use the "MyClass()" constructor, the following won't work :
    $_SESSION['obj_my_class'] = new MyClass();
If you don't believe me, you can have a look in the directory "session.save_path" (default /var/lib/php4) where is stored the session's file. You will see this :
    obj_my_class|N;
and not your complete class!

It took me almost one day to understand what was happening... :-(
varrah NO_GARBAGE_OR_SPAM AT mail DOT ru
13-Jan-2006 10:21
Worked with Andrea, so the script is now updated to support at least UTF-8 correctly. Details can be found at http://www.sitepoint.com/blogs/2004/04/22/ serializing-php-data-structures-for-javascript (had to insert space after the 22/  otherwise the link was too long and comments engine didn't want to pass it :-) )
varrah NO_GARBAGE_OR_SPAM AT mail DOT ru
10-Jan-2006 02:52
andrea at 3site dot it gave a link for a JavaScript serialization class, but be prepared! This class works only on single-byte symbols, since JS str.length property gives the length of the string in SYMBOLS, not bytes (as PHP serialize() does), so a Unicode string JS-serialized in a way like:

strSerialized = "s:" + strOriginal.length + ":" + strOriginal;

will not be unserialized correctly by PHP.
MC_Gurk at gmx dot net
03-Jan-2006 04:44
If you are going to serialie an object which contains references to other objects you want to serialize some time later, these references will be lost when the object is unserialized.
The references can only be kept if all of your objects are serialized at once.
That means:

$a = new ClassA();
$b = new ClassB($a); //$b containes a reference to $a;

$s1=serialize($a);
$s2=serialize($b);

$a=unserialize($s1);
$b=unserialize($s2);

now b references to an object of ClassA which is not $a. $a is another object of Class A.

use this:
$buf[0]=$a;
$buf[1]=$b;
$s=serialize($buf);
$buf=unserialize($s);
$a=$buf[0];
$b=$buf[1];

all references are intact.
Alexander Podgorny
03-Dec-2005 08:47
Here is an example of a base class to implement object persistence using serialize and unserialize:

<?
class Persistent
{
    var
$filename;
       
   
/**********************/
   
function Persistent($filename)
    {
       
$this->filename = $filename;
        if(!
file_exists($this->filename)) $this->save();
    }
   
/**********************/
   
function save()
    {
        if(
$f = @fopen($this->filename,"w"))
        {
            if(@
fwrite($f,serialize(get_object_vars($this))))
            {
                @
fclose($f);
            }
            else die(
"Could not write to file ".$this->filename." at Persistant::save");
        }
        else die(
"Could not open file ".$this->filename." for writing, at Persistant::save");
       
    }
   
/**********************/
   
function open()
    {
       
$vars = unserialize(file_get_contents($this->filename));
        foreach(
$vars as $key=>$val)
        {           
            eval(
"$"."this->$key = $"."vars['"."$key'];");
        }
    }
   
/**********************/
}

?>

When an object is extended from this one it can be easily saved and re-opened using it's own methods as follows:

<?

class foo extends Persistent
{
   var
$counter;
   function
inc()
   {
      
$this->counter++;
   }
}

$fooObj = new $foo;
$foo->open();
print
$foo->counter; // displays incrementing integer as page reloads
$foo->inc();
$foo->save();

?>
andrea at 3site dot it
26-Nov-2005 06:31
Hello!
Here you can find a JavaScript Object that should serialize JS vars for PHP and unserialize PHP vars for JavaScript.
http://www.devpro.it/javascript_id_102.html

Please read notes inside the code to know more about vars compatibility.

It was created to resolve AJAX interaction and maybe usefull for other situations .... such:

<?php
// example nested array
$myarray = array(
   
true,
   
123,
    array(
       
'nested',
        array(
           
1,
           
'test'=>false
       
)
    ),
   
'other'=>'value'
);
// array serializzation
$serialized = serialize($myarray);
?>
<script type="text/javascript" src="PHP_Serializer.js"></script>
<script type="text/javascript">
// function to dump an object
function showObject(obj, level) {
    var l = '';
    var tmp = '';
    for(var a = 0; a < level; a++)
        l += '[_]';
    for(var a in obj) {
        var type = typeof(obj[a]);
        if(type == 'object')
            tmp += showObject(obj[a], (level + 1));
        else
            tmp += l + ' key: ' + a + ' = value: ' +
            obj[a] + ' < ' + type + '\n';
    }
    return tmp;
}
// new PHP_Serializer variable
var php = new PHP_Serializer();
// dinamyc JS var creation
var myJSvar = php.unserialize("<?php echo str_replace('"', '\\"', $serialized); ?>");
// look at dump :-)
alert(showObject(myJSvar, 0));
</script>

Regards
pavic at ieee dot org
01-Nov-2005 08:18
Hi, if You get code like
d:234 and than string You wanted, it's the problem, that
s dot marechal at jejik dot com
explanied.

Well, here is a workaround for that problem, function safe serialize, which won't produce that unwanted chars...

function safe_serialize($string) {
    return preg_replace("/(\n)|(\r)/"," ",$string);
}
stephen dot adamson at smius dot com
01-Nov-2005 06:40
If you are serializing an object to store it in the database, using __sleep() can save you some space. The following code will not store empty (null) variables in the serialized string. For my purposes this saved a lot of space, since some of the member variables would not be given values.

function __sleep()
{
    $allVars = get_object_vars($this);
    $toReturn = array();
    foreach(array_keys($allVars) as $name)
    {
        if (isset($this->$name))
        {
            $toReturn[] = $name;
        }
    }
    return $toReturn;
}
php barryhunter co uk
29-Oct-2005 01:51
if you wanting to do something similar to 'mwwaygoo AT hotmail DOT com', then you may want to look at the built in function var_export.

"var_export() gets structured information about the given variable. It is similar to var_dump()  with one exception: the returned representation is valid PHP code."
Sean at http://seanj dot jcink dot com
11-Oct-2005 11:07
Very short function I made to turn arrays into a string for fwriting, doesnt create unnecessary commas either:

<?
function arraytostring($array){
$text.="array(";
$count=count($array);
foreach (
$array as $key=>$value){
$x++;
if (
is_array($value)) {$text.=$key."=>".arraytostring($value); continue;}
$text.="\"$key\"=>\"$value\"";
if (
$count!=$x) $text.=",";
}
$text.=")";
return
$text;
}
?>
eggyknap at gmail dot com
11-Oct-2005 06:01
My thanks to the editor who pointed out the serialization bug. According to the bug report, this should be fixed in version 5.0.4, and is confirmed fixed in v 5.0.5. Unfortunately I'm not in a position to update my installation, but I found that passing the serialized string through addslashes before saving it to the database does the trick. It may be a bit inefficient, but it works.
eggyknap at gmail dot com
09-Oct-2005 06:12
[Editor's note: This has been fixed. Protected and private members were serialized with a leading \0 (zero byte). Bug report here, http://bugs.php.net/29865 - aidan@php.net]

Be careful trying to serialize objects containing private or protected data members. It appears that the serialization process includes characters in the result string to indicate the visibility of each member, but the characters used to denote protected or private data are outside the normal character set and can cause problems as you pass them through applications. I haven't found the culprit in my particular case, so I can't say that this is a bug in PHP, but it certainly is causing me some annoyance in my particular situation.
mwwaygoo AT hotmail DOT com
18-Jul-2005 05:03
Hello people,

I had major problems getting serialize to work properly, as I wanted to sync two databases via email, and needed a way of converting a retrieved row to a string. It works the reverse of array(), in that it creates a statement that you can use to evaluate to the original array, so I called it unarray().
Its a recursive function (self calling), so it doesnt matter how complex the array is.

<?php

$source
=array(1,4,'x'=>'test');
$text=unarray($source);

$destination=array(); // prime the variable incase of failure.
eval('$destination='.$text);
print_r($destination);

// unarray.php    REVERSE of array();

function unarray($array, $first=TRUE)
{
   
$text="";
    if(
is_array($array))
    {
       
$text.="array(";
        while(list(
$key,$value)=each($array))
        {
            if(
is_string($key))
            {
               
$text.="'".$key."'";
            }
            else
            {
               
$text.=$key;
            }
           
$text.="=>";
           
$text.=unarray($array[$key], FALSE);
        }
       
$text=$text."), ";
    }
    else
    {
        if(
is_string($array))
        {
           
$text.="'".addslashes($array)."', ";
        }
        else
        {
            if(
is_bool($array))
            {
                if(
$array)
                {
                   
$text.="TRUE, ";
                }
                else
                {
                   
$text.="FALSE, ";
                }
            }
            else
            {
                if(
is_null($array))
                {
                   
$text.="NULL, ";
                }
                else
                {
                   
$text.=$array.", ";
                }
            }
        }
    }
    if(
$first) $text=substr($text,0,-2).";";
    return
$text;
}

?>

p.s. I realise that it also creates unnecessary commas, but these are ignored when re-creating it. array(1,2,) is the same as array(1,2).
abductee _at_ texture _minus_ editor.com
14-Jun-2005 01:44
wiart at yahoo dot com wrote:
>As you can see, the original array :
>$arr["20041001103319"] = "test"
>
>after serialize/unserialize is:
>$arr[683700183] = "test"

yepp, and i can explain it.

the internal compiler of php does not hit anys rule wich foces him to make that number a string during serialisation. since it becomes an integer and php supports 32bit interger not arbitary bitwidth this is what happens:

"20041001103319"
equals hexadecimal:

0x123A28C06FD7h

if you cut away the frontpart cutting down to 32bis,
you get:

0x28C06FD7h

wich equals 683700183.

of, for those of you who speak binary:

20041001103319 =
100100011101000101000110000000110111111010111bin

----cut-away----00101000110000000110111111010111bin
=683700183

so, what can you do to prevent stuff like this?
eihter use only numbers between 0..9999999999
or force strings, best way ist to add a character
like

foo["c2342303"]

cheers, abductee
s dot marechal at jejik dot com
04-Feb-2005 01:42
In response to gafunchal NOSPAN at inf dot ufrgs dot br:

What you are seeing is not a bug in PHP's serialize() function, but a side-effect of the floating point type. Floats are inherintly inaccurate and you are seeing it's inaccuracy.

More information about IEEE floats:
http://www.math.byu.edu/~schow/work/IEEEFloatingPoint.htm
http://www.codeguru.com/forum/printthread.php?t=323835
gafunchal NOSPAN at inf dot ufrgs dot br
23-Jan-2005 01:33
(please, excuse my poor English)

'serialize' does strange things with floats, this code:

  $a = 3.14;
  $s = serialize($a);
  $fp = fopen("storage", "w");
  fwrite($fp, $s);
  fclose($fp);

outputs something like (PHP 5.0.2):

d:3.140000000000000124344978758017532527446746826171875;

I wonder why serialize doesn't store data (not only float, I mean all types of data) in a more 'economic' format. Maybe binary is not the best option (there can be trouble storing it in databases), but there are still a lot of other possibilities.
cjmeyer at npcc dot net
24-Dec-2004 08:16
More on troubles with recursive object references and serialization.

In my PHP 4.2.2 the solution suggested above (by james at gogo dot co dot nz), to pass a reference to the object to serialize(), does not help.  There are still multiple copies of the objects woken up, and the recursive reference is no longer recursive.

The only solution I have found is to use the __sleep and __wakeup magic functions to only serialize the link one-way, then recreate it manually on unserialize.  This isn't too difficult;  here is some code demonstrating this approach:

class A {
  var $data = Null;
  var $b = Null;

  function A($data, $bData) {
    $this->data = $data;
    $this->b = new B(&$this, $bData);
  }

  function printData() {
    print 'A thinks A data is ' . $this->data . "\n";
    print 'A thinks B data is ' . $this->b->data . "\n";
  }

  function __sleep() {
    print "A is going to sleep.\n";
    return array('data', 'b');
  }

  function __wakeup(){
    print "A is waking up.\n";
    $this->b->reLinkA($this);
  }

}

class B {
  var $data = Null;
  var $a = Null;

  function B(&$a, $data) {
    $this->a =& $a;
    $this->data = $data;
  }

  function printData() {
    print 'B thinks A data is ' . $this->a->data . "\n";
    print 'B thinks B data is ' . $this->data . "\n";
  }

  function __sleep() {
    print "B is going to sleep.\n";
    return array('data');
  }

  function __wakeup(){
    print "B is waking up.\n";
  }

  function reLinkA(&$a) {
    $this->a =& $a;
  }

}

$a = new A("origAdata", "origBdata");

print '<pre>';

print "I think A data is " . $a->data . "\n";
print "I think B data is " . $a->b->data . "\n";
$a->printData();
$a->b->printData();

$serA = serialize($a);
$newA = unserialize($serA);

$newA->data = 'newAdata';
$newA->b->data = 'newBdata';

print "I think new A data is " . $newA->data . "\n";
print "I think new B data is " . $newA->b->data . "\n";
$newA->printData();
$newA->b->printData();
wiart at yahoo dot com
16-Dec-2004 12:40
Warning: on 64 bits machines,  if you use a long string only composed of numbers as a key in an array and serialize/unserialize it, you can run into problems:

an example code:
$arr["20041001103319"] = 'test';
var_dump( $arr);
$arr_in_str = serialize($arr);
print "Now result is: $arr_in_str<BR />";
$final_arr = unserialize($arr_in_str);
print "The final unserialized array:<BR />";
var_dump($final_arr);

The result:
array(1) { [20041001103319]=>  string(4) "test" }
Now result is: a:1:{i:20041001103319;s:4:"test";}
The final unserialized array:
array(1) { [683700183]=> string(4) "test" }

As you can see, the original array :
$arr["20041001103319"] = "test"

after serialize/unserialize is:
$arr[683700183] = "test"

As you can see,  the key has changed ...

Apparently a problem of implicit casting + integer overflow (I posted a PHP bug report: http://bugs.php.net/bug.php?id=31117)

I tested with the latest 4.3.10 compiled on my laptop (32 bits, Mandrake 9.1) --> no such problem. But compiled on AMD 64 bits (Red Hat Taroon), the problem is present.

Hope this will help some of you to not loose almost a whole day of debugging ;-)
richard dot prangnell at ntlworld dot com
12-Dec-2004 11:08
Although the serialise function has its proper uses, it is a relatively slow process. I try to avoid using it wherever possible in the interests of performance. You can store text records in a database as plain text even when it contains PHP variables. The variable values are lost, naturally; but if they can easily be re-attached to retrieved records, zillions of clock cycles can be saved simply by using the str_replace() function:

  if($convert)
  {
    $mainContent = str_replace('$fixPath', $fixPath, $mainContent);
    $mainContent = str_replace('$theme', $theme, $mainContent);
  }

The above snippet is used in a CMS project. $fixPath contains  something like '.' or '..' to prepend relative paths (allowing the record to be used by scripts located in different parts of the directory hierarchy) and $theme inserts the name of the users custom page rendering scheme, which obviously would be undefined at record storage time anyway.
corey at eyewantmedia dot com
08-Dec-2004 07:47
If this helps anybody, I was looking for a few quick calls to cache stuff to files. I settled on the below functions. By the way, if I am doing something stupid here, I'd appreciate some comments on that also. Anyway, on with the code:

First, the usage:

//Use:

$var = tuncache('MyCacheName');
if (is_null($var)) {
    $var = 'a really expensive process';
    $check = tcache('MyCacheName', $var, '+25 minutes');
    if (is_null($check)) {
        die('I need to reset my permissions or get a bigger hard drive');
    }
}

//use $var now

Now, the functions:

//uses strtotime to decide how long to cache $cacheVar based on $lifespan
//so anything but a timestamp works. +1 day works, 09/14/2010 works, etc
function tcache($cacheName, $cacheVar, $lifespan=null) {
    if (!is_null($lifespan)) { //a lifespan was provided
        if (strpos($lifespan, '+') === 0 || strpos($lifespan, '-') === 0) {
            //Have to do this to counter for bug in php5 to
            //properly evaluate now to do the date math
            $endTime = strtotime(date('m/d/Y H:i:s') . ' ' .$lifespan);
        } else {
            //we can safely use anything else I think
            $endTime = strtotime($lifespan);
        }
    } else {
        //cache forever (forever being ten years) until manually deleted
        $endTime = strtotime(date('m/d/Y H:i:s') . ' +10 years');
    }
   
    $cVal = serialize($cacheVar);
    $file = tFindcache($cacheName);
    $result = true;
   
    $f = fopen($file, 'w');
    if ($f === false) {
        $result = null; //barf if we can't open the file
    } else { //write the cache
        fwrite($f, $endTime . "\n");
        fwrite($f, $cVal);
        fclose($f);
    }
   
    return $result;
}

function tuncache($cacheName) {
    $file = tFindCache($cacheName);

    if (is_readable($file)) {
        //open file
        $f = fopen($file, 'r');
        $time = time();
        $expTime = trim(fgets($f));
        //check time
        if ($time > $expTime) {
            //It expired
            $result = null;
        } else {
            //Read it and unserialize it
            $data = fread($f, filesize($file));
            $result = unserialize($data);
        }
    } else {
        //barf
        $result = null;
    }
   
    return $result;
}

//just to set a few options for setting where to save stuff
function tFindCache($cacheName) {
    if (isset($_ENV['PHP_CACHE_PATH'])) {
        $cachePath = $_ENV['PHP_CACHE_PATH'];
    } else if (isset($_SERVER['PHP_CACHE_PATH'])) {
        $cachePath = $_SERVER['PHP_CACHE_PATH'];
    } else {
        $cachePath = './'; //Potential danger here
    }
   
    $cachePath .= 'PHP_CACHE_' . $cacheName . '.cache';
   
    return $cachePath;
}
01-Dec-2004 10:30
This is just a modification of what Alan Reddan (areddan at silverarm dot ie) posted below.

I figured it would be faster than walking an array, and it works wonderfully with cookies

<?php
$data
[qwerty] = "blah";
$data[1][a] = "1aa";
$data[2][b] = "2bb";
$data[3][c] = ";;;;;;";
$data[name][first] = "Bob";
$data[name][last] = "Jones";
$data[val] = "This is a real long test string, to see how well the compression works!";

//To Serialise Call :
$string = gzcompress(serialize($data), 9);
setcookie("my_var", $string, time()+60*60*24*60, '/');
//print "String: $string\n<br>"; //uncomment to see serialized array

//To Unserialize Call
if (isset($_COOKIE[my_var])) {
 
$array = unserialize(gzuncompress($_COOKIE[my_var]));

  echo
"<pre>";
 
print_r($array);
  echo
"</pre>";
}
?>

you can replace gzcompress with base64_encode and gzuncompress with base64_decode to have a similar experience

Alan, thanks for the tip though, it got me where I wanted to be!
paul at moveNOtoSPAMiceland DOT com
18-Nov-2004 05:29
I was trying to submit a serialized array through a hidden form field using POST and was having a lot of trouble with the quotes. I couldn't figure out a way to escape the quotes in the string so that they'd show up right inside the form, so only the characters up to the first set of quotes were being sent.

My solution was to base64_encode() the string, put that in the hidden form field, and send that through the POST method. Then I decoded it (using base64_decode()) on the other end. This seemed to solve the problem.
Alexei dot Filine at cern dot ch
24-Oct-2004 04:57
A simple way to transfer PHP variables between PHP scripts running on different hosts can be done with HTTP_Request PEAR module. I think it is much more fast way than one done with XML-RPC but less portable (there were described ways to exchange vars between Perl and PHP below). Recieved PHP obects are required to be created before recieving by class definition similar to definition used on sending side. A script sending variable must output nothing except data sent by function 'sendVariable' so a 'composite variable' is to be used to transfer some variables by one request.

<?php
// exchange-protocol.php
ini_set( 'include_path', '.' );
require_once
"config.php"; // set $PEAR_path
ini_set( 'include_path', ini_get( 'include_path' ).$PEAR_path );

// PEAR module
require_once "HTTP/Request.php";

// magic words for HTTP header
$gzcompressed_serialized_type = 'application/serialized_gzcompressed_PHP_variable';
$serialized_type = 'application/serialized_PHP_variable';

$compression_flag_name = '_compressionFlag_';

// Date in the past
header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );

// always modified
header( "Last-Modified: ".gmdate( "D, d M Y H:i:s" )." GMT" );

// returns non-zero on success
function recieveVariable( $url,
              &
$var,
             
$user = '',
             
$passw = '',
                 
$compression_flag = 1 ) {

    global
$gzcompressed_serialized_type;
    global
$serialized_type;
   
$req =& new HTTP_Request( "" );
     
$req->setURL( $url );
     
$req->setMethod( HTTP_REQUEST_METHOD_POST );

     
// set user/password if required
   
if ( $user && $passw ) {
         
$req->addPostData( $user,
                            
$passw );
    }
     
$response = $req->sendRequest();
     
$req->clearPostData();
    if (
$compression_flag ) {
       
$req->addPostData( $compression_flag_name, 1 );
    }
      if (
PEAR::isError( $response ) ) {
            echo
$response->getMessage();
      } else {
           
$header = $req->getResponseHeader();
            if (
$req->getResponseCode() != 200 ||
                 ! (
$header['content-type'] == $gzcompressed_serialized_type ||
                   
$header['content-type'] == $serialized_type ) ) {
                   
// type error message
                   
echo $req->getResponseBody();
            } else {
                    if (
$header['content-type'] == $gzcompressed_serialized_type )
{
                           
$data = gzuncompress( $req->getResponseBody() );
                    } else {
                           
$data = $req->getResponseBody();
                    }
                   
$var = unserialize( $data );
            return
1;
            }
    }
    return
0;
}

// just for extra flexibility, if data chunk is small enough we can skip gzipping on the sending side: $compression_flag = 0;
// in other case we use client preference: $compression_flag = $_REQUEST[$compression_flag_name];
function sendVariable( &$var, $compression_flag = 1 ) {

    global
$gzcompressed_serialized_type;
    global
$serialized_type;
   
// Date in the past
   
header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );

   
// always modified
   
header( "Last-Modified: "