以前の記事でLaravelのconfig()等でよく使われているドット記法(dot notation)での配列アクセスをピュアPHPで実装しました。
今回は逆に、ドット記法で記したキーの1次元配列を多次元配列に展開していきます。
「Illuminate\Support\Arr::undot()」でサポートされていたりしますが
![](https://laravel.com/img/og-image.jpg)
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing ...
敢えてピュアPHPで実装していきます。
使用する配列の例
▼dot-notated-data.php
<?php
return [
'database.connection' => 'mysql',
'database.host' => '127.0.0.1',
'database.user' => 'dbadmin',
'database.password' => 'Pass_w0rd',
'database.dbname' => 'webapp',
'database.tables.users.columns.id' => 'user id, primary key',
'database.tables.users.columns.name' => "user's name, required",
'database.tables.users.columns.passowrd' => 'login password, required, encrypted',
'database.tables.users.columns.email' => "user's email",
'database.tables.posts.columns.id' => 'post id, primary key',
'database.tables.posts.columns.user_id' => "user's id, required",
'database.tables.posts.columns.title' => 'title of the post',
'database.tables.posts.columns.content' => 'content of the post',
];
オペレーターファイル
▼「undotArray.php」
<?php
// クラス読込
require __DIR__ . '/Arr.php';
// 配列データ読込
$data = require __DIR__ . '/dot-notated-data.php';
// 配列アクセッサーのインスタンス生成
$array = new MyLib\Arr();
// 多次元配列を出力
print_r($array->undot($data));
※「Arr.php」は次で作成します。
多次元配列化処理クラス
▼処理部のコア
※ $key がドット(.)を含んでいる前提
※ $key をドット(.)で分割し最下層の要素から順次構築
protected function dig(string $key, mixed $value)
{
$results = $value;
$keys = explode('.', $key);
while ($k = array_pop($keys)) {
$results = [$k => $results];
}
return $results;
}
※ 「dig()」から受け取ったものを「array_merge_recursive()」でマージ
public function undot(array $array)
{
$results = [];
foreach ($array as $key => $value) {
if (str_contains($key, '.')) {
$results = array_merge_recursive($results, self::dig($key, $value));
continue;
}
$results[$key] = $value;
}
return $results;
}
▼「Arr.php」の完成形
<?php
namespace MyLib;
class Arr
{
public function undot(array $array)
{
$results = [];
foreach ($array as $key => $value) {
if (str_contains($key, '.')) {
$results = array_merge_recursive($results, self::dig($key, $value));
continue;
}
$results[$key] = $value;
}
return $results;
}
protected function dig(string $key, mixed $value)
{
$results = $value;
$keys = explode('.', $key);
while ($k = array_pop($keys)) {
$results = [$k => $results];
}
return $results;
}
}
実行結果
Array
(
[database] => Array
(
[connection] => mysql
[host] => 127.0.0.1
[user] => dbadmin
[password] => Pass_w0rd
[dbname] => webapp
[tables] => Array
(
[users] => Array
(
[columns] => Array
(
[id] => user id, primary key
[name] => user's name, required
[passowrd] => login password, required, encrypted
[email] => user's email
)
)
[posts] => Array
(
[columns] => Array
(
[id] => post id, primary key
[user_id] => user's id, required
[title] => title of the post
[content] => content of the post
)
)
)
)
)
コメント