Structure of a Serialized PHP String

Structure of a Serialized PHP string

The basic structure is as follows:

Scalar types:

  1. Booleans are serialized as:

    b:<i>;

    where <i> is an integer with a value of either 0 (false) or 1 (true).

  2. Integers are serialized as:

    i:<i>;

    where <i> is the integer value.

  3. Floats are serialized as (with d meaning double):

    d:<f>;

    where <f> is the float value.

  4. Strings are serialized as:

    s:<i>:"<s>";

    where <i> is an integer representing the string length of <s>, and <s> is the string value.

Special types:

  1. null is simply serialized as:

    N;

Compound types:

  1. Arrays are serialized as:

    a:<i>:{<elements>}

    where <i> is an integer representing the number of elements in the array, and <elements> zero or more serialized key value pairs:

    <key><value>

    where <key> represents a serialized scalar type, and <value> any value that is serializable.

  2. Objects are serialized as:

    O:<i>:"<s>":<i>:{<properties>}

    where the first <i> is an integer representing the string length of <s>, and <s> is the fully qualified class name (class name prepended with full namespace). The second <i> is an integer representing the number of object properties. <properties> are zero or more serialized name value pairs:

    <name><value>

    where <name> is a serialized string representing the property name, and <value> any value that is serializable.

    There's a catch with <name> though:

    <name> is represented as

    s:<i>:"<s>";

    where <i> is an integer representing the string length of <s>. But the values of <s> differs per visibility of properties:

    a. With public properties <s> is the simple name of the property.

    b. With protected properties, however, <s> is the simple name of the property, prepended with \0*\0 — an asterix, enclosed in two NUL characters (i.e. chr(0)).

    c. And with private properties, <s> is the simple name of the property, prepended with \0<s>\0<s>, enclosed in two NUL characters, where <s> is the fully qualified class name.


There are a few other cases, such as R:<i>;, that represents references, that I haven't mentioned here (because I honestly haven't figured out the exact workings of it yet), but this should give you a decent idea about PHP's serializing mechanism.

Can a Serialized PHP Object be formatted for easy readability?

Here is a great 1 liner:

<?php echo "<pre>" . print_r(unserialize($yourvar), 1) . "</pre>"; ?>

structure of serialized data in a MySQL database for SitePress

This is PHP serialized data, a format that is largely unused now thanks to the prevalence of JSON. It was quite popular among PHP developers at one stage. It fell into disuse because there are some security concerns with php serialize and unserialize and also because of the rise of JSON. However it's still found in some apps.

use unserialize to convert to a php object

unserialize — Creates a PHP value from a stored representation

Note: You haven't posted a valid serialized string (it's truncated)

the PHP variable handling function, serialize()

You probably wouldn't want to serialise a variable as such, but it is useful to serialise objects and other complex data structures.

Instead of creating a database table with loads of columns, create a table with a primary key and a blob and serialise a class or array into it. That way you have an infinitly flexible system where if you need to add new data to the database table you don't have to add more columns.

This is one silly example, but persisting objects into a database is seriously useful if you think about it.

Beautify PHP serialized strings

You can do something like this:

var_dump(unserialize($serializedData));

You may write a simple console program.

How to use php serialize() and unserialize()

A PHP array or object or other complex data structure cannot be transported or stored or otherwise used outside of a running PHP script. If you want to persist such a complex data structure beyond a single run of a script, you need to serialize it. That just means to put the structure into a "lower common denominator" that can be handled by things other than PHP, like databases, text files, sockets. The standard PHP function serialize is just a format to express such a thing, it serializes a data structure into a string representation that's unique to PHP and can be reversed into a PHP object using unserialize. There are many other formats though, like JSON or XML.


Take for example this common problem:

How do I pass a PHP array to Javascript?

PHP and Javascript can only communicate via strings. You can pass the string "foo" very easily to Javascript. You can pass the number 1 very easily to Javascript. You can pass the boolean values true and false easily to Javascript. But how do you pass this array to Javascript?

Array ( [1] => elem 1 [2] => elem 2 [3] => elem 3 ) 

The answer is serialization. In case of PHP/Javascript, JSON is actually the better serialization format:

{ 1 : 'elem 1', 2 : 'elem 2', 3 : 'elem 3' }

Javascript can easily reverse this into an actual Javascript array.

This is just as valid a representation of the same data structure though:

a:3:{i:1;s:6:"elem 1";i:2;s:6:"elem 2";i:3;s:7:" elem 3";}

But pretty much only PHP uses it, there's little support for this format anywhere else.

This is very common and well supported as well though:

<array>
<element key='1'>elem 1</element>
<element key='2'>elem 2</element>
<element key='3'>elem 3</element>
</array>

There are many situations where you need to pass complex data structures around as strings. Serialization, representing arbitrary data structures as strings, solves how to do this.

serialize a large array in PHP?

As quite a couple other people answered already, just for fun, here's a very quick benchmark (do I dare calling it that ? ) ; consider the following code :

$num = 1;

$list = array_fill(0, 5000, str_repeat('1234567890', $num));

$before = microtime(true);
for ($i=0 ; $i<10000 ; $i++) {
$str = serialize($list);
}
$after = microtime(true);

var_dump($after-$before);
var_dump(memory_get_peak_usage());

I'm running this on PHP 5.2.6 (the one bundled with Ubuntu jaunty).
And, yes, there are only values ; no keys ; and the values are quite simple : no object, no sub-array, no nothing but string.

For $num = 1, you get :

float(11.8147978783)
int(1702688)

For $num = 10, you get :

float(13.1230671406)
int(2612104)

And, for $num = 100, you get :

float(63.2925770283)
int(11621760)

So, it seems the bigger each element of the array is, the longer it takes (seems fair, actually). But, for elements 100 times bigger, you don't take 100 times much longer...


Now, with an array of 50000 elements, instead of 5000, which means this part of the code is changed :

$list = array_fill(0, 50000, str_repeat('1234567890', $num));

With $num = 1, you get :

float(158.236332178)
int(15750752)

Considering the time it took for 1, I won't be running this for either $num = 10 nor $num = 100...


Yes, of course, in a real situation, you wouldn't be doing this 10000 times ; so let's try with only 10 iterations of the for loop.

For $num = 1 :

float(0.206310987473)
int(15750752)

For $num = 10 :

float(0.272629022598)
int(24849832)

And for $num = 100 :

float(0.895547151566)
int(114949792)

Yeah, that's almost 1 second -- and quite a bit of memory used ^^

(No, this is not a production server : I have a pretty high memory_limit on this development machine ^^ )


So, in the end, to be a bit shorter than those number -- and, yes, you can have numbers say whatever you want them to -- I wouldn't say there is a "limit" as in "hardcoded" in PHP, but you'll end up facing one of those :

  • max_execution_time (generally, on a webserver, it's never more than 30 seconds)
  • memory_limit (on a webserver, it's generally not muco more than 32MB)
  • the load you webserver will have : while 1 of those big serialize-loop was running, it took 1 of my CPU ; if you are having quite a couple of users on the same page at the same time, I let you imagine what it will give ;-)
  • the patience of your user ^^

But, except if you are really serializing long arrays of big data, I am not sure it will matter that much...

And you must take into consideration the amount of time/CPU-load using that cache might help you gain ;-)

Still, the best way to know would be to test by yourself, with real data ;-)


And you might also want to take a look at what Xdebug can do when it comes to profiling : this kind of situation is one of those it is useful for!

What type of structure is this data?

It's serialized data, most likely by the php function serialize()

http://php.net/manual/en/function.serialize.php

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().

Example:

<?php
$obj = new stdclass;
$obj->prop1 = 1;
$obj->prop2 = "two";
$arr = array(0, 1, 2, array("key" => "value", "another key" => "another value"), $obj);
print serialize($arr);
?>

will output:

a:5:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;a:2:{s:3:"key";s:5:"value";s:11:"another key";s:13:"another value";}i:4;O:8:"stdClass":2:{s:5:"prop1";i:1;s:5:"prop2";s:3:"two";}}

And to explain a snippet of yours, take:

a:18:{
i:0;
a:7:{
i:0;
i:10;
i:1;
s:5:"Email";
i:2;
s:10:"user_email";
i:3;
s:4:"text";
i:4;
s:1:"y";
i:5;
s:1:"y";
i:6;
s:1:"y";
}

It's saying the data is an array with 18 elements a:18, the element at index 0 i:0 is an array of 7 elements a:7, the element at index 0 of that array i:0 is an integer with the value 10 i:10, the element at index 1 i:1 is a string of length 5 s:5 with the value email. and so on.

a var_dump of just the first element from your serialized data gives:

array(1) {
[0]=>
array(7) {
[0]=>
int(10)
[1]=>
string(5) "Email"
[2]=>
string(10) "user_email"
[3]=>
string(4) "text"
[4]=>
string(1) "y"
[5]=>
string(1) "y"
[6]=>
string(1) "y"
}
}

To serialize your particular snippet - well, there's a few ways to do it and i don't have a wordpress handy to verify it, but one way would simply be to represent it in php like this:

$input = array('type' => 'select');
$opts = array(array('value' => 1, 'text' => '1'), array('value' => 2, 'text' => '2'));
$input['options'] = $opts;
$serialized = serialize($input);

which would give you a string that looks like
a:2:{s:4:"type";s:6:"select";s:7:"options";a:2:{i:0;a:2:{s:5:"value";i:1;s:4:"text";s:1:"1";}i:1;a:2:{s:5:"value";i:2;s:4:"text";s:1:"2";}}}



Related Topics



Leave a reply



Submit