serialize
(PHP 4, PHP 5, PHP 7, PHP 8)
serialize — 値の保存可能な表現を生成する
説明
値の保存可能な表現を生成します。
型や構造を失わずに PHP の値を保存または渡す際に有用です。
シリアル化された文字列を PHP の値に戻すには、 unserialize() を使用してください。
パラメータ
value
-
シリアル化する値。 serialize() は、resource および一部の object 以外のすべての型を処理します。(下記の注を参照ください) 自分自身への参照を含む配列を serialize() することも可能です。 シリアル化した配列/オブジェクト内の 循環参照も保存されます。その他の参照は失われます。
PHP は、シリアル化の前にまずメンバ関数 __serialize() または __sleep() のコールを試みます。ここで、シリアル化の前のオブジェクトの後始末処理 などを行います。同様に、unserialize() で オブジェクトを復元した際にはメンバ関数 __unserialize() または __wakeup() がコールされます。
注意:
オブジェクトの private メンバは、メンバ名の前にクラス名がつきます。 また protected メンバはメンバ名の前に '*' がつきます。 前に付加されるこれらの値の前後には null バイトがついています。
戻り値
value
の保存可能なバイトストリーム表現を含む文字列を返します。
これはバイナリ文字列であり、null バイトを含む可能性もあることに注意しましょう。 保存したり利用したりするときも、null バイトが含まれることを想定しておかないといけません。 たとえば、serialize() の出力をデータベースに格納するときには、 通常は CHAR 型や TEXT 型ではなく BLOB 型を使わないといけません。
例
例1 serialize() の例
<?php
// $session_data はカレントユーザーのセッション情報を含む多次元配列を
// 保持しています。リクエストの最後にこれをデータベースに保存するために
// serialize() を使用します。
$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, array_reverse($sqldata))) {
/* 何か問題があったようです.. */
}
}
?>
注意
注意:
PHP の組み込みオブジェクトの多くはシリアル化できないことに注意しましょう。しかし、 Serializable インターフェイスを実装しているか、あるいはマジックメソッド __serialize()/__unserialize() または __sleep()/__wakeup() を実装していればシリアル化することができます。 内部クラスがこれらの要件を満たしていない場合は、確実にシリアル化することはできません。
この規則には歴史的な例外もあり、 上記のインターフェイスやマジックメソッドを実装していない内部オブジェクトの中にも シリアル化可能なものがあります。
serialize() でオブジェクトをシリアル化するときに、 名前空間を指定したクラスの名前の先頭にあるバックスラッシュは含めません。これは互換性を高めるためです。
参考
- unserialize() - 保存用表現から PHP の値を生成する
- var_export() - 変数の文字列表現を出力または返す
- json_encode() - 値を JSON 形式にして返す
- オブジェクトのシリアル化
- __sleep()
- __wakeup()
- __serialize()
- __unserialize()
User Contributed Notes 7 notes
<?
/*
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.
*/
?>
Please! please! please! DO NOT serialize data and place it into your database. Serialize can be used that way, but that's missing the point of a relational database and the datatypes inherent in your database engine. Doing this makes data in your database non-portable, difficult to read, and can complicate queries. If you want your application to be portable to other languages, like let's say you find that you want to use Java for some portion of your app that it makes sense to use Java in, serialization will become a pain in the buttocks. You should always be able to query and modify data in the database without using a third party intermediary tool to manipulate data to be inserted.
I've encountered this too many times in my career, it makes for difficult to maintain code, code with portability issues, and data that is it more difficult to migrate to other RDMS systems, new schema, etc. It also has the added disadvantage of making it messy to search your database based on one of the fields that you've serialized.
That's not to say serialize() is useless. It's not... A good place to use it may be a cache file that contains the result of a data intensive operation, for instance. There are tons of others... Just don't abuse serialize because the next guy who comes along will have a maintenance or migration nightmare.
There is a type not mentioned in the user notes so far, 'E'. This is the newer Enum class that can be utilised:
login_security|E:25:"Permission:manageClient"
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.
Serializing floating point numbers leads to weird precision offset errors:
<?php
echo round(96.670000000000002, 2);
// 96.67
echo serialize(round(96.670000000000002, 2));
// d:96.670000000000002;
echo serialize(96.67);
// d:96.670000000000002;
?>
Not only is this wrong, but it adds a lot of unnecessary bulk to serialized data. Probably better to use json_encode() instead (which apparently is faster than serialize(), anyway).
When you serialize an array the internal pointer will not be preserved. Apparently this is the expected behavior but was a bit of a gotcha moment for me. Copy and paste example below.
<?php
//Internal Pointer will be 2 once variables have been assigned.
$array = array();
$array[] = 1;
$array[] = 2;
$array[] = 3;
//Unset variables. Internal pointer will still be at 2.
unset($array[0]);
unset($array[1]);
unset($array[2]);
//Serialize
$serializeArray = serialize($array);
//Unserialize
$array = unserialize($serializeArray);
//Add a new element to the array
//If the internal pointer was preserved, the new array key should be 3.
//Instead the internal pointer has been reset, and the new array key is 0.
$array[] = 4;
//Expected Key - 3
//Actual Key - 0
echo "<pre>" , print_r($array, 1) , "</pre>";
?>
Closures cannot be serialized:
<?php
$func = function () {echo 'hello!';};
$func(); // prints "hello!"
$result = serialize($func); // Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed'
?>