シリアル化とは、おそらく、いくつかの変数を文字列のバイト ストリームに変換することで、送信と保存が容易になります。もちろん、送信や保存とは何の関係もありません。重要なのは、文字列形式に変換し直すことができ、元のデータ構造を維持できることです。
PHP にはシリアル化関数が多数あります (serialize())。この関数は、任意の変数値 (リソース変数を除く) を文字列の形式に変換することができ、文字列をファイルに保存したり、セッションとして登録したり、curl を使用して変換したりすることもできます。 GET/POST をシミュレートして変数を転送し、RPC の効果を実現します。
シリアル化された変数を PHP オリジナルの変数値に変換したい場合は、unserialize() 関数を使用できます。
1. 変数のシリアル化
シリアル化とその保存形式を説明する簡単な例を見てみましょう。
整数型:
$var = 23;
echoserialize($var);
出力:
i:23;
浮動小数点型:
$
var = 1.23
;
出力:
d
:1.229999999982236431605997495353221893310546875;
エコーシリアル化($var);
$var = "私は変数です";
echoserialize($var);
出力:
s:16:"これは文字列です";
s:8: "私は変数です";
ブール型:
$var = true;
エコーシリアル化($var);
$var = false;
エコーシリアル化($var);
出力:
b:1;
b:0;
上記の基本型のシリアル化後の状況は、次のとおりです。
変数タイプ: [可変長:] 変数値、
つまり、最初の文字は変数のタイプを表します。分割を表します。変数の長さはオプションです。つまり、文字列タイプでは使用できますが、最後のものは変数値であり、「;」で終わります。
たとえば、整数 23 がシリアル化されると、i:23 になります。この場合、長さはなく、型と変数値だけが存在します。i はコロンで区切られた整数を表し、整数値 23 は浮動小数点を含めて後で保存されます。 type(double) Byte型)は同じです。ブール値の場合、タイプは b (ブール値) です。true の場合、シリアル値は 1 です。false の場合、値は 0 です。
文字列
値の場合、中央に追加の保存値があり、文字列「This is a string」などの文字列の長さの値が保存され、生成されるシリアル値は s:16:「This is a string」になります。 "; s は型を表す文字列です。中央の 16 は文字列の長さです。中国語の場合、中国語の各文字は 2 文字に格納されます。たとえば、文字列「I am a variable」、生成されたシリアル値は :s:8:"I am a variable" です。長さは 8 文字です。
次に、配列変数のシリアル化に焦点を当てます。
配列変数:
$var = array("abc", "def", "xyz", "123");
エコーシリアル化($var);
出力:
a:4:{i:0;s:3:"abc";i:1;s:3:"def";i:2;s:3:"xyz"; i:3;s:3:"123";} は
、配列 $var をシリアル化して取得した文字列値です。$var 配列には、「abc」、「def」、「xyz」、「123」という 4 つの文字列要素が含まれています。簡単にするために、シリアル化されたデータを配列形式でリストします:
a:4:
{
i:0;s:3:"abc";
i:1;s:3:"def";
i:2;s:3:"xyz";
i:3;s:3:"123";
開始文字列 a:4:{...} まず、最初の文字 a は変数の型 (配列) を保存し、2 番目の 4 は配列要素を保存します
。
の数は合計4つあり、その後に{}で囲まれた配列要素の内容が入ります。たとえば、最初の配列要素: i:0;s:3:"abc"; i は、現在の配列要素のインデックス値の型が整数で、値が 0、要素の値の型が s (文字列) であることを表します。 )、数値は 3、特定の値は「abc」、セミコロンで終わるなど、次の配列要素についても同様です。
文字列を要素インデックスとして使用するとどうなるかを見てみましょう:
$var = array("index1"=>"abc", "index2"=>"def", "index3"=>"xyz", "index4" = >"123");
echoserialize($var);
出力:
a:4:{s:6:"index1";s:3:"abc";s:6:"index2";s:3:"def";s:6: "index3";s:3:"xyz";s:6:"index4";s:3:"123";}
配列スタイルに変更後:
a:4:
{
s:6:"インデックス1";s:3:"abc";
s:6:"インデックス2";s:3:"def";
s:6:"インデックス3";s:3:"xyz";
s:6:"インデックス4";s:3:"123";
実際には、開始インデックスが文字列を保存する形式に変更されることを除いて、上記とあまり変わりません
。
最初の項目はインデックスです。 値: s:6:"index1"; s はタイプ、6 はインデックス文字列の長さ、「index1」はインデックスの値です。次の s:3:"abc"; は要素の値です。これは理解するのが簡単なので、詳細は説明しません。
上記のことから、基本的なデータ型のシリアル化について一般的に理解できました。実際、独自のシリアル化関数を構築したり、この観点から拡張して変数の交換を容易にする独自のシリアル化プログラムを開発したりできます。
もちろん、実際には、この関数を使用して配列またはその他の変数を文字列にシリアル化し、curl 関数を使用して GET/POST 関数をシミュレートし、ユーザーがアクションを実行せずにリモート サーバーからデータを取得することもできます。
2. オブジェクトのシリアル化
オブジェクトのシリアル化も比較的一般的な機能で、オブジェクトをシリアル化して文字列に変換し、保存または送信できます。
まず例を見てみましょう:
クラス TestClass
{
変数$a;
var $b;
関数 TestClass()
{
$this->a = "これは a";
$this->b = "これは b";
関数
getA()
{
$this->a を返します。
関数
getB()
{
$this->b を返す;
}
新しい
テストクラス;
$str = シリアル化($obj);
echo $str;
出力結果:
O:9:"TestClass":2:{s:1:"a";s:9:"This is a";s:1:"b";s:9:"This is b";}
オブジェクトのシリアル化後の文字列を分析してみましょう。
O:9:"テストクラス":2:
{
s:1:"a";s:9:"これは a";
s:1:"b";s:9:"これは b";
まず、オブジェクト自体の内容を確認します。O:9:"TestClass":2:O は、これがオブジェクト タイプ (オブジェクト) であることを示し、9 はオブジェクトの名前を表し、2 はオブジェクトの数を表します
。
財産。 2 つの属性の内容を確認します。
s:1:"a";s:9:"This is a"; 実際、これは配列の最初の項目 s:1:"a と似ています。 "; は説明属性名です。 、2 番目の項目 s:9: "This is a"; は属性値を説明します。次のプロパティも同様です。
まず、オブジェクトのシリアル化の応用について説明します。以下の内容は PHP マニュアルからのものであり、原文は変更されていません。
serialize() は、PHP に格納できる任意の値のバイト ストリーム表現を含む文字列を返します。 unserialize() は、この文字列を使用して元の変数値を再構築できます。シリアル化を使用してオブジェクトを保存すると、オブジェクト内のすべての変数が保存されます。オブジェクト内の関数は保存されず、クラス名のみが保存されます。
オブジェクトを unserialize() できるようにするには、オブジェクトのクラスを定義する必要があります。つまり、page1.php でクラス A のオブジェクト $a をシリアル化すると、クラス A を指し、$a 内のすべての変数の値を含む文字列が得られます。それを page2.php で逆シリアル化し、クラス A のオブジェクト $a を再構築したい場合は、クラス A の定義が page2.php に存在する必要があります。これは、たとえば、クラス A の定義をインクルード ファイルに配置し、このファイルを page1.php と page2.php の両方にインクルードすることで実現できます。
<?php
// 株式会社クラッサ:
クラスA
{
var $one = 1;
関数 show_one()
{
$this->one をエコーします。
}
}
// page1.php:
include("classa.inc");
$a = 新しい A;
$s = シリアル化($a);
// $s をどこかに保存して、page2.php が見つけられるようにします
$fp = fopen("ストア", "w");
fputs($fp, $s);
fclose($fp);
// ページ 2.php:
// この行は通常の逆シリアル化に必要です
include("classa.inc");
$s = implode("", @file("store"));
$a = unserialize($s);
// これで、$a オブジェクトの show_one() 関数が使用できるようになります。
$a->show_one();
?>
セッションを使用しており、session_register() を使用してオブジェクトを登録する場合、これらのオブジェクトは各 PHP ページの最後で自動的にシリアル化され、後続の各ページで自動的に逆シリアル化されます。これは基本的に、これらのオブジェクトがセッションの一部になると、どのページにも表示できることを意味します。
これらのクラスがすべてのページで使用されない場合でも、すべてのページにこれらの登録済みオブジェクトのクラス定義を含めることを強くお勧めします。これが行われず、オブジェクトが逆シリアル化されてもそのクラスが定義されていない場合、そのオブジェクトは関連付けられたクラスを失い、使用可能な関数がまったくない stdClass のオブジェクトになり、非常に役に立ちません。
したがって、上記の例で session_register("a") を実行して $a がセッションの一部になる場合、classa.inc ファイルは、page1.php と page2.php だけでなく、すべてのページに含まれる必要があります。
もちろん、シリアル化されたオブジェクトは実際には多くの場所に適用できます。もちろん、PHP 5 ではシリアル化の処理方法が異なります。マニュアルの内容を見てみましょう。serialize
() は、クラス内に __sleep というマジック名を持つ関数があるかどうかをチェックします。その場合、関数はシリアル化の前に実行されます。これはオブジェクトをクリアし、シリアル化する必要があるオブジェクト内のすべての変数の名前を含む配列を返す必要があります。
__sleep を使用する目的は、オブジェクトが持つデータベース接続を閉じたり、保留中のデータを送信したり、同様のクリーンアップ タスクを実行したりすることです。さらに、この機能は、完全に保管する必要のない非常に大きなオブジェクトがある場合にも役立ちます。
逆に、unserialize() は、マジック名 __wakeup を持つ関数の存在をチェックします。この関数は、オブジェクトが持つ可能性のあるリソースが存在する場合、それを再構築できます。
__wakeup を使用する目的は、シリアル化中に失われた可能性のあるデータベース接続を再確立し、他の再初期化タスクを処理することです。