[PHP] PHPオブジェクトと配列の変換まとめ

2018年7月9日月曜日

PHP

ファイルから読み込んだ値をオブジェクトにしたり、逆に外部に渡したい時にはオブジェクトのプロパティを連想配列にしたい場合は結構ある。
DBの場合はPDOなどフレームワークがやってくれることも多いけど、自分でやりたい場合はどうすればいいか。

配列からオブジェクトを生成する

新しくオブジェクトを作りたい場合は配列をobject型にキャストするだけ。
$obj = (object)[ 'foo' => 'orange', 'bar' => 'green' ];
var_dump($obj);
object(stdClass)#1 (2) {
  ["foo"]=>
  string(6) "orange"
  ["bar"]=>
  string(5) "green"
}

stdClassと言うのはPHPオブジュエクトのデフォルトのクラスみたいなもので、object型にキャストすると、stdClassのオブジェクトになる。

http://php.net/manual/ja/reserved.classes.php

既存のオブジェクトにプロパティを追加する

新しくオブジェクトを作りたい場合はobjectへのキャストだけでいいけど、既存のオブジェクトに追加したい場合は可変変数を使う。

http://php.net/manual/ja/language.variables.variable.php

可変変数というのは変数に文字列を格納して、その文字列が変数名を表すようにできる機能。
これはオブジェクトのプロパティにも使えて、以下のようになる。
$obj = new stdClass();
var_dump($obj);

$prop = 'prop1';
$obj->$prop = 'blue';
var_dump($obj);
object(stdClass)#2 (0) {
}
object(stdClass)#2 (1) {
  ["prop1"]=>
  string(4) "blue"
}

これで、元々$objにprop1というプロパティがなかったけど、追加される。
ポイントは $obj->prop ではなく、$obj->$prop としてアクセスしているところ。

配列から既存のオブジェクトに一気に追加したければ、以下のようにする。
$arr = [ 'foo' => 'orange', 'bar' => 'green' ];
foreach ($arr as $key => $value) {
    $obj->$key = $value;
}
object(stdClass)#2 (3) {
  ["prop1"]=>
  string(4) "blue"
  ["foo"]=>
  string(6) "orange"
  ["bar"]=>
  string(5) "green"
}

オブジェクトから配列を生成する

単純にarray型にキャストしてみる。
$arr = (array)$obj;
var_dump($arr);
array(3) {
  ["prop1"]=>
  string(4) "blue"
  ["foo"]=>
  string(6) "orange"
  ["bar"]=>
  string(5) "green"
}

一見、うまくいってそうだけど、protectedやprivateのプロパティを持ったオブジェクトをarrayにキャストしてみると以下のようになる。
class SomeClass {
    protected $foo = 'orange';
    private $bar = 'green';
    public $bazz = 'yellow';
}
$obj = new SomeClass();
var_dump($obj);
$arr = (array)$obj;
var_dump($arr);
object(SomeClass)#1 (3) {
  ["foo":protected]=>
  string(6) "orange"
  ["bar":"SomeClass":private]=>
  string(5) "green"
  ["bazz"]=>
  string(6) "yellow"
}
array(3) {
  ["*foo"]=>
  string(6) "orange"
  ["SomeClassbar"]=>
  string(5) "green"
  ["bazz"]=>
  string(6) "yellow"
}

配列のキー名に"*"やクラス名が付加されてしまった。
これはPHPの配列キャストの仕様らしい。

http://php.net/manual/ja/language.types.array.php#language.types.array.casting

そこで、publicプロパティだけで配列を作りたい場合には、get_object_varsを使う。

http://php.net/manual/ja/function.get-object-vars.php
$obj = new SomeClass();
$arr = get_object_vars($obj);
var_dump($arr);
array(1) {
  ["bazz"]=>
  string(6) "yellow"
}

既存の配列に追加したい場合は、単純に上記で作成した配列を追加すればいい。