塩焼きブログ

塩焼きに関しての研究内容を公開しています

PHPで連想配列をオブジェクトにする

設定値など配列で保存されている値をアロー演算子でアクセスできるようにしたい。この場合は(object)でキャストするだけで可能でした。

$config = [
  'a' => 1,
  'b' => 2,
  'c' => 3
];
var_dump($config);
var_dump((object) $config);
$ php hoge.php
array(3) {
  'a' =>
  int(1)
  'b' =>
  int(2)
  'c' =>
  int(3)
}
class stdClass#1 (3) {
  public $a =>
  int(1)
  public $b =>
  int(2)
  public $c =>
  int(3)
}

しかしこれだと多次元配列には対応していないので直下だけがオブジェクトになり、それ以降の階層は配列のまま残ってしまいます。

$config = [
  'a' => 1,
  'b' => [
    'd' => 2,
    'e' => 3
  ],
  'c' => 4
];
var_dump((object) $config);
$ php hoge.php
class stdClass#1 (3) {
  public $a =>
  int(1)
  public $b =>
  array(2) {
    'd' =>
    int(2)
    'e' =>
    int(3)
  }
  public $c =>
  int(4)
}

これを解決するにはjson_encodeしてからjson_decodeすると良いです。10万回実行したところ0.53sと割りと高速です。

$config = [
  'a' => 1,
  'b' => [
    'd' => 2,
    'e' => 3
  ],
  'c' => 4
];
var_dump(json_decode(json_encode($config)));
$ php hoge.php
class stdClass#1 (3) {
  public $a =>
  int(1)
  public $b =>
  class stdClass#2 (2) {
    public $d =>
    int(2)
    public $e =>
    int(3)
  }
  public $c =>
  int(4)
}

しかしなんだか行儀が悪いので、再帰的にキャストするような目的に沿った以下の関数を作ってもいいかもしれません。でもこれは10万回あたり3.653sと遅めでしたw

function arrayToObject($mixed) {
  if (!is_array($mixed)) {
    return $mixed;
  }

  return (object) array_map(function($value) {
    return arrayToObject($value);
  }, $mixed);
};

$config = [
  'a' => 1,
  'b' => [
    'd' => 2,
    'e' => 3
  ],
  'c' => 4
];
var_dump(arrayToObject($config));

連想配列なら素直に連想配列として使う方が良いんでしょうか。json_decodeでJSONをパースした時にオブジェクトになる件を受けて、もっとオブジェクト化したい欲を感じてしまいました。