php serialize()およびunserialize()の使用方法


125

私の問題は非常に基本的です。

phpで正確に何serialize()unserialize()意味するかについて、自分のニーズを満たす例は見つかりませんでしたか?それらは例を示すだけです-配列をシリアル化し、説明されていない形式で出力を表示します。彼らの専門用語を通過する基本的な概念を理解することは本当に難しいです。

編集:

<?php

$a= array( '1' => 'elem 1', '2'=> 'elem 2', '3'=>' elem 3');
print_r($a);
echo ("<br></br>");
$b=serialize($a);
print_r($b);

?>

出力:

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

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

2番目の出力を理解できません。さらに、php配列を使用する前にシリアル化する必要がある状況の例を誰かに教えてもらえますか?


10
「2次出力」についてまだ興味がある場合は、かなり単純です。a=配列、3 = {}内の3つの要素のサイズです。その中に、i = integer / indexが1に等しく、len 6の文字列が「elem 1」に等しく、整数が2に等しいなどがあります。そのように読んだとき、それはかなり明確です。複数レベルの配列/オブジェクトが簡単に含まれることを想像できますが、変更はあまり賢明ではありません。整合性を確保するために、変更をシリアル化解除してからシリアル化する必要があります。
Grizly、2015

2
@IstiaqueAhmed、「誰でもphp配列を使用する前にシリアル化する必要がある状況の例を誰か教えてもらえますか」については、そのような例がstackoverflow.com/a/30436890/632951
Pacerier

@grizlyありがとう、私は2年間そのような答えを探していました、それを説明する方法も、その機能を使用する理由を関連付ける方法もわかりませんでした。答えをありがとう
isaacewing

回答:


169

PHPの配列、オブジェクト、またはその他の複雑なデータ構造は、実行中のPHPスクリプトの外部で転送または保存したり、その他の方法で使用したりすることはできません。このような複雑なデータ構造をスクリプトの1回の実行を超えて永続化したい場合は、それをシリアル化する必要があります。これは、データベース、テキストファイル、ソケットなど、PHP以外のものでも処理できる「より低い共通項」に構造を置くことを意味します。標準のPHP関数serializeそのようなことを表現するための形式にすぎずデータ構造をPHPに固有の文字列表現にシリアル化し、を使用してPHPオブジェクトに逆変換できますunserialize。ただし、JSONやXMLなど、他にも多くの形式があります。


この一般的な問題を例にとります:

PHP 配列をJavaScript に渡すにはどうすればよいですか?

PHPとJavaScriptは、文字列を介してのみ通信できます。文字列"foo"をJavaScriptに非常に簡単に渡すことができます。1JavaScriptに非常に簡単に番号を渡すことができます。ブール値truefalse簡単にJavaScriptに渡すことができます。しかし、この配列をJavaScriptにどのように渡しますか?

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

答えはシリアル化です。PHP / Javascriptの場合、JSONは実際にはより優れたシリアル化形式です。

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

JavaScriptは、これを実際のJavaScript配列に簡単に逆転できます。

これは、同じデータ構造の表現と同じくらい有効です。

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

しかし、ほとんどの場合、PHPでのみ使用され、他の場所ではこの形式のサポートはほとんどありません。
これは非常に一般的であり、十分にサポートされています。

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

複雑なデータ構造を文字列として渡す必要がある状況は数多くあります。文字列として任意のデータ構造を表すシリアル化は、これを行う方法を解決します。


1
あなたの説明は私が期待していたものに近づいているようです。私の編集を見て頂けますか?
Istiaque Ahmed 2011

1
a:3:{i:1; s:6: "elem 1"; i:2; s:6: "elem 2"; i:3; s:のa、i、sなどの説明は何ですか。 7: "elem 3";}?そして、気にしない場合は、配列をシリアライズしてjsに送信する例(この投稿のテーマには関係ない可能性があります)。
Istiaque Ahmed 2011

2
私が知っている限り、そのフォーマットの正式な仕様はほとんどありませんが、推測できますか?i:1=整数1、s:6:"elem 1"= 6文字の文字列 "elem 1" ...そして、どのような例を求めているのですか、私は1つ与えたと思いますか?
だます

"しかし、この配列をJavaScriptにどのように渡しますか?配列([1] => elem 1 [2] => elem 2 [3] => elem 3)" ...正確なコードスニペット
Istiaque Ahmed

echo json_encode($array);どの程度正確合格するかは、状況によって異なります。それに夢中になりすぎないでください。
だます

27

PHPのserialize()およびunserialize()の使用法

http://freeonlinetools24.com/serialize

echo '<pre>';
// say you have an array something like this 
$multidimentional_array= array(
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 4, 7) 
       ),
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 5, 7) 
       ),
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 8, 7) 
    )
);

// serialize 
$serialized_array=serialize($multidimentional_array);
print_r($serialized_array);

これはあなたにこのような出力を与えます

a:3:{i:0;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:4;i:2;i:7;}}i:1;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:5;i:2;i:7;}}i:2;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:8;i:2;i:7;}}}

元の配列に戻したい場合は、PHPのunserialize()関数を使用してください。

$original_array=unserialize($serialized_array);
var_export($original_array);

これが役に立てば幸い


7

PHP値を保存可能にしたい場合は、それを文字列値に変換する必要があります。それが、serialize()が行うことです。そしてunserialize()は逆のことを行います。


1
「保存可能」とはどういう意味ですか?私はあなたが参照したページを通過しました。phpとmysql(必要な場合)で例を示してください。
Istiaque Ahmed 2011

2
@Istiaque Ahmedたとえば、配列をディスク上のファイルに保存する場合、配列を直接保存することはできませんが、それを格納可能な値に変更すると、文字列になります。
xdazz 2011

しかし、php mysqlでシリアル化せずに、変数をデータベースに直接挿入できます。説明お願いします。
Istiaque Ahmed 2011

9
「変数をシリアル化せずにデータベースに挿入できます」。これは、基本的なデータ型(文字列、整数、数値)にのみ当てはまります。配列やオブジェクトをDBやファイルシステムに直接挿入することはできません。それが何でserialize()ありunserialize()、のために作られています。
lorenzo-s

あなたはいくつかの情報を取得し、どこかに保存/送信する準備ができているphpスクリプトでそれを使っていくつかの作業を行います。予想されるデータと正確に一致するテーブルを作成するオプションがありますが、これも面倒であり、一致するコードも作成する必要があるため、作業負荷が本質的に2倍になります。さらに、データベースの変更にはコードの変更が必要、またはその逆です。シリアル化すると、2つの列ID int(10)と情報BLOBを持つテーブルを簡単に作成できます。Serialiseは挿入する文字列を提供し、unserializeはデータを元の状態に戻します。それがうまくいかない場合があります、php docsはそれらをカバーします。
Chris

7
<?php
$a= array("1","2","3");
print_r($a);
$b=serialize($a);
echo $b;
$c=unserialize($b);
print_r($c);

このプログラムを実行し、出力をエコーし​​ます

a:3:{i:0;s:1:"1";i:1;s:1:"2";i:2;s:1:"3";}


ここで
a =配列のサイズ
i =配列番号
の数s =配列値のサイズ

シリアライズを使用してデータの配列をデータベースに
格納し、使用するデータを取得してUNシリアライズできます。


6

ほとんどの記憶媒体は文字列型を格納できます。配列やオブジェクトなどのPHPデータ構造を直接格納することはできません。また、データ記憶媒体とPHPを結合するため、格納しないでください。

代わりに、serialize()これらの構造体の1つを文字列として保存できます。文字列表現からで逆シリアル化できますunserialize()

json_encode()およびjson_decode()(および一般的なJSON)に精通している場合、概念は似ています。


jsonに詳しい。PHPのことはまだわかりません。私の投稿を編集しました
Istiaque Ahmed 2011

json_encodeがある場合、なぜシリアライズが必要なのですか?ご存知でしたら説明してください。ありがとう。
Yevgeniy Afanasyev 2017

1
@YevgeniyAfanasyevたぶん、データの一部のサブセットでは必要ないでしょう。しかし、私serialize()はJSONよりも古いと思います。
アレックス

5

お願いします!お願いします!お願いします!データをシリアル化してデータベースに配置しないでください。Serializeはそのように使用できますが、リレーショナルデータベースのポイントとデータベースエンジンに固有のデータ型が欠けています。これを行うと、データベース内のデータが移植不可能になり、読みにくくなり、クエリが複雑になる可能性があります。アプリケーションを他の言語に移植できるようにする場合、たとえば、Javaを使用するのが理にかなっているアプリケーションの一部にJavaを使用したい場合、シリアライゼーションはお尻の痛みになります。サードパーティの仲介ツールを使用して挿入するデータを操作しなくても、常にデータベース内のデータをクエリおよび変更できる必要があります。

コード、移植性の問題があるコード、および他のRDMSシステム、新しいスキーマなどに移行するのがより難しいデータを維持することは本当に困難になります。また、シリアル化したフィールド。

それはserialize()が役に立たないと言っているわけではありません。そうではありません...たとえば、データを多用する操作の結果が含まれるキャッシュファイルが適しています。他にもたくさんあります...シリアライズを乱用しないでください。次の人がやって来ると、メンテナンスや移行の悪夢が起こるからです。

serialize()とunserialize()の良い例は次のようになります:

$posts = base64_encode(serialize($_POST));
header("Location: $_SERVER[REQUEST_URI]?x=$posts");

ページのシリアル化を解除します

if($_GET['x']) {
   // unpack serialize and encoded URL
   $_POST = unserialize(base64_decode($_GET['x']));
}

2
提供されたコードにはいくつかのセキュリティの脆弱性が含まれているため、貼り付けコードを入手してコピーする人には警告する必要があります。
ダニエルW.

与えられたコードは、searilize関数とunserialize関数を使用する方法の単なる例です。
Avnish alok

2

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

値の保存可能な表現を生成します。これは、型や構造を失うことなく、PHPの値を保存または渡すのに役立ちます。

基本的に、これはphpの配列またはオブジェクトを受け取り、それを文字列に変換します(その後、必要に応じて送信または保存できます)。

Unserializeは、文字列をオブジェクトに戻すために使用されます。


「保存可能な表現」の説明は何ですか?
Istiaque Ahmed 2011

誰かがphp配列を取得してデータベースに格納したいときに使用される、serializeのみが表示されます。シリアル化して、データベースの標準の文字列フィールドに出力を保存し、それを再度使用するときに取得してシリアル化を解除できます。
MrGlass、2011

1

基本的に、配列またはオブジェクトをシリアル化するときは、単純に有効な文字列形式に変換して、phpスクリプトの外部に簡単に格納できるようにします。

  1. オブジェクトの状態をデータベースに保存するには、serializeを使用します(例としてUserクラスを取り上げます)次に、データのシリアル化を解除して、以前の状態をオブジェクトに読み込みます(メソッドはシリアライザではなく、使用できるようにオブジェクトクラスを含める必要があります)それ)
    • ユーザーのカスタマイズ

オブジェクトについては、魔法の__sleepおよび__wakeupメソッドを使用する必要があることに注意してください。__sleepは、serialize()によって呼び出されます。sleepメソッドは、永続化したいオブジェクトから値の配列を返します。

__wakeupはunserialize()によって呼び出されます。ウェイクアップメソッドは、シリアル化されていない値を受け取り、オブジェクト内のそれらの値で初期化する必要があります。

phpとjsの間でデータを渡すには、json_encodeを使用してphp配列を有効なjson形式に変換します。または逆の方法-JSON.parese()を使用して、出力データ(文字列)を有効なjsonオブジェクトに変換します。ローカルストレージを利用するためにそれをしたいと思うでしょう。(オフラインデータアクセス)


json_encodeがある場合、なぜシリアライズが必要なのですか?ご存知でしたら説明してください。ありがとう。
Yevgeniy Afanasyev 2017

1
シリアライズとアンシリアライズを使用するときに照合される魔法のメソッドをカスタマイズできるというメリットがあります。つまり、Json_encode()とjson_decode()をさらに使用することができ、各オブジェクトはこの機能を独自の方法で処理できます。これがあなたがそれらを使いたい理由です。
DevWL 2017

1
それにはもっともっとあります。より多くの情報のためこの回答を参照してくださいstackoverflow.com/questions/804045/...
DevWL

1
json_encodeの方が高速です(使用しているPHPバージョンによって異なります)、jsonはstdClassとしてデコードし、実際のClassインスタンスとしてシリアライズされたオブジェクトをシリアル化解除します。UTF-8エンコードを変更せずに保持するためにJSONにいくつかの設定を行う必要があります。シリアル化によってエンコードは変更されません。データクロスプラットフォームでJSONを使用する場合は、PHPのみで作業する場合、__ sleepおよび__wakeupマジックメソッドを使用してシリアル化をカスタマイズできます。
DevWL 2017

0

はい、できます。システムを追跡する必要があると仮定します。システムに複数の管理者とサブ管理者がいる場合、これらのすべてが情報を挿入、更新、または編集できます。後で、誰がこの変更を行ったかを知る必要があります。この問題を解決するには、シリアル化が必要です。

  **Explain:**Create a table named history which stores all changes. Each time there is a change insert a new row in this table. It might have this fields:

  history(id,target_table(name of the table), target_id (ID of the saved entry),create/edit/change data (serialized data of the saved row),date)

これがお役に立てば幸いです。


-1
preg_match_all('/\".*?\"/i', $string, $matches);
foreach ($matches[0] as $i => $match) $matches[$i] = trim($match, '"');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.