suin.io

[PHP] 配列を文字列に変換して取っておく4つの方法

suin2011年8月9日

配列をデータベースやテキストファイルに保存したいときってありますよね。リレーショナルデータベース的には、ちゃんと最適化すべきだけど、並び替えや検索する必要がない場合は、とりあえず配列を文字列として保存したりします。serialize()関数を使う方法はよく知られています。この関数以外にも、PHPでは配列を文字列に変換できるものがあります。このエントリーでは、serialize()var_export()json_encode()http_build_query()の4つの使い方について書きます。

今回文字列化を試す変数

今回文字列化を試す変数は、bool型・int型・float型・string型・添字配列・連想配列を含んだ連想配列です。

$data = array(
    'bool'   => true,
    'int'    => 1,
    'float'  => 1.23,
    'string' => 'foobar',
    'array'  => array('apple', 'orange', 'strawberry'),
    'key-value' => array(
        'jp' => 'Japan', 
        'us' => 'USA', 
        'cn' => 'China',
    ),
);

1. http_build_query()

http_build_query()関数は、配列をクエリーストリング形式に変換します。この関数はPHP5から利用できます。

$query = http_build_query($data);
var_dump($query);
// string(170) "bool=1∫=1&float=1.23&string=foobar&array%5B0%5D=apple&array%5B1%5D=orange&array%5B2%5D=strawberry&key-value%5Bjp%5D=Japan&key-value%5Bus%5D=USA&key-value%5Bcn%5D=China"

デコードには、parse_str()関数を使います。第二引数を指定しないとextract()関数のように、配列のキーで変数を定義します。第二引数を変数すると、デコードした結果がその変数に代入されます。parse_str()関数はすべて文字列型に解釈するので注意が必要です。

parse_str($query, $queryImported);

var_dump($queryImported);
/*
array(6) {
  ["bool"]=>
  string(1) "1"
  ["int"]=>
  string(1) "1"
  ["float"]=>
  string(4) "1.23"
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/

var_dump($data === $queryImported); // false

2. json_encode()

json_encode()関数は、JSON形式の文字列に変換します。この関数はPHP5.2で導入されました。

$json = json_encode($data);
var_dump($json);
// string(143) "{"bool":true,"int":1,"float":1.23,"string":"foobar","array":["apple","orange","strawberry"],"key-value":{"jp":"Japan","us":"USA","cn":"China"}}"

再び配列に戻すときはjson_decode()関数を使います。第二引数を指定しないと、戻り値がオブジェクト型になります。戻り値を配列型として受け取るには、第二引数にtrueを指定する必要があります。

$jsonImported = json_decode($json, true);

var_dump($jsonImported);
/*
array(6) {
  ["bool"]=>
  bool(true)
  ["int"]=>
  int(1)
  ["float"]=>
  float(1.23)
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/

3. serialize()

この関数は変数を文字列化できることでよく知られています。変換された文字列は型・大きさ・値を保持するようになっています。

$serial = serialize($data);
var_dump($serial);
// string(285) "a:6:{s:4:"bool";b:1;s:3:"int";i:1;s:5:"float";d:1.229999999999999982236431605997495353221893310546875;s:6:"string";s:6:"foobar";s:5:"array";a:3:{i:0;s:5:"apple";i:1;s:6:"orange";i:2;s:10:"strawberry";}s:9:"key-value";a:3:{s:2:"jp";s:5:"Japan";s:2:"us";s:3:"USA";s:2:"cn";s:5:"China";}}"

シリアライズされた文字列を、再び配列に戻すにはunserialize()関数を使います。元のデータをしっかり復元してくれます。

$serialImported = unserialize($serial);
var_dump($serialImported);
/*
array(6) {
  ["bool"]=>
  bool(true)
  ["int"]=>
  int(1)
  ["float"]=>
  float(1.23)
  ["string"]=>
  string(6) "foobar"
  ["array"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "orange"
    [2]=>
    string(10) "strawberry"
  }
  ["key-value"]=>
  array(3) {
    ["jp"]=>
    string(5) "Japan"
    ["us"]=>
    string(3) "USA"
    ["cn"]=>
    string(5) "China"
  }
}
*/
var_dump($data === $serialImported); // true

4. var_export()

var_export()関数はPHPとして解釈可能な文字列に変換します。第二引数に何も指定しないと、文字列に変換した結果が出力されます。変数に代入するときは第二引数にtrueを指定します。

$php = var_export($data, true);
var_dump($php);
/*
string(267) "array (
  'bool' => true,
  'int' => 1,
  'float' => 1.23,
  'string' => 'foobar',
  'array' => 
  array (
    0 => 'apple',
    1 => 'orange',
    2 => 'strawberry',
  ),
  'key-value' => 
  array (
    'jp' => 'Japan',
    'us' => 'USA',
    'cn' => 'China',
  ),
)"
*/

var_export()関数には、unserialize()関数のようにインポートする直接的に対応する関数はありません。そのかわりに、eval()関数で文字列を評価します。

eval('$phpImported = '.$php.';');
var_dump($phpImported);
var_dump($data === $phpImported); // true
RELATED POSTS