もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

設定ファイルを記述する言語TOMLを触ってみた。

こんばんは。

以前Rustの記事を上げた時に、設定ファイルでTOMLという拡張子のファイルを触りました。

僕は初めて聞いたんですが、結構有名なのかな・・・?

感触的にはiniファイル的な書き方だったので、PHPのパーサあるのかなとpakagist探すとやはり有りました。

yosymfony/toml

以前の記事ではちょろっと紹介しただけだったので、せっかくなので今回触ってみます。

参考サイト

設定ファイル記述言語 TOML

インストール

$ mkdir toml_test
$ cd toml_test
$ composer require yosymfony/toml
Using version ^1.0 for yosymfony/toml
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing yosymfony/parser-utils (v1.0.0): Downloading (100%)         
  - Installing yosymfony/toml (v1.0.1): Downloading (100%)         
Writing lock file
Generating autoload files

やってみた

1. 簡単な読み込み

$ touch test.toml
$ touch sample.php

test.toml

AWS_SECRET_KEY="1234567890qwertyuiop"

sample.php

<?php
require_once './vendor/autoload.php';

use Yosymfony\Toml\Toml;

$toml_data = Toml::ParseFile('test.toml');
print_r($toml_data);

実行してみる

$ php sample.php
Array
(
    [AWS_SECRET_KEY] => 1234567890qwertyuiop
)

なるほどなるほど。という感じですね。

これくらいは簡単な感じです。

もう少し複雑な設定ファイル用意してみます。

2. testのtomlファイルを複雑にしてみる

test.toml

AWS_SECRET_KEY = "1234567890qwertyuiop" # AWSのシークレットキー
USE_DATABASE   = true                   # データベースを使用するかどうか
BARTH_DAY      = 1984-01-21             # 誕生日

# 簡易メモ
MEMO = """
データベースはMYSQLにしました。
AWSも使ってます。
SendGridとかも使いたいな。"""

# コメント
COMMENT = """
こんにちは\
Kojirockです。\
フリーランスのエンジニアやってます。\
お仕事ください\
"""

# データーベース設定
[DATABASE]
    PORT     = 3306
    USER     = "kojirock"
    PASSWORD = "1234567890qwertyuiop"
    HOST     = "localhost"

# 家族構成
[FAMILY.MYSELF]
    name = "kojirock"
[FAMILY.WIFE]
    name = "nyoro"
[FAMILY.SON]
    name = "yutoton"

# 好きなもの
[[LIKE]]
    [[LIKE.MUSIC]]
        name = "エリック・クラプトン"
    [[LIKE.MUSIC]]
        name = "モンパチ"

    [[LIKE.FOOD]]
        name = "ラーメン"

    [[LIKE.MOVIE]]
        name = "バック・トゥ・ザ・フューチャー"

実行してみる

$ php sample.php
Array
(
    [AWS_SECRET_KEY] => 1234567890qwertyuiop
    [USE_DATABASE] => 1
    [BARTH_DAY] => DateTime Object
        (
            [date] => 1984-01-21 00:00:00.000000
            [timezone_type] => 3
            [timezone] => Asia/Tokyo
        )

    [MEMO] => データベースはMYSQLにしました。
AWSも使ってます。
SendGridとかも使いたいな。
    [COMMENT] => こんにちはKojirockです。フリーランスのエンジニアやってます。お仕事ください
    [DATABASE] => Array
        (
            [PORT] => 3306
            [USER] => kojirock
            [PASSWORD] => 1234567890qwertyuiop
            [HOST] => localhost
        )

    [FAMILY] => Array
        (
            [MYSELF] => Array
                (
                    [name] => kojirock
                )

            [WIFE] => Array
                (
                    [name] => nyoro
                )

            [SON] => Array
                (
                    [name] => yutoton
                )

        )

    [LIKE] => Array
        (
            [0] => Array
                (
                    [MUSIC] => Array
                        (
                            [0] => Array
                                (
                                    [name] => エリック・クラプトン
                                )

                            [1] => Array
                                (
                                    [name] => モンパチ
                                )

                        )

                    [FOOD] => Array
                        (
                            [0] => Array
                                (
                                    [name] => ラーメン
                                )

                        )

                    [MOVIE] => Array
                        (
                            [0] => Array
                                (
                                    [name] => バック・トゥ・ザ・フューチャー
                                )

                        )

                )

        )

)

datetimeが返ってくるのいいですね。それにbooleanも判定してくれるのも地味に嬉しい。

(print_rで表示しているので、1になっていますがUSE__DATABASEの型はbooleanでした)

コメントも # で書けて直感的でした。

この判定ってphp7以上だからかな?と思ったので、php5系にして、おなじtomlを読み込んでみます。

3. php5系にして試してみる。

phpenvで5系に戻す

$ phpenv versions
  system
  5.6.9
* 7.1.5 (set by /path/to/.anyenv/envs/phpenv/version)

$ phpenv local 5.6.9
5.6.9

$ php -v
PHP 5.6.9 (cli) (built: Feb 27 2018 00:47:13) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.5.3, Copyright (c) 2002-2017, by Derick Rethans

yosymfony/tomlのバージョンを下げる

$ cat composer.json
{
    "require": {
        "yosymfony/toml": "0.x-dev"
    }
}

$ composer update
Download composer.phar ...
All settings correct for using Composer
Downloading...
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 1 update, 1 removal
  - Removing yosymfony/parser-utils (v1.0.0)
  - Removing yosymfony/toml (v1.0.1)
  - Installing yosymfony/toml (0.x-dev b30fa1f): Cloning b30fa1fc0a from cache
Writing lock file
Generating autoload files

sample.phpの修正

php5系は Toml::ParseFile() は使えないようなので、 Toml::parse を使います。

<?php
require_once './vendor/autoload.php';

use Yosymfony\Toml\Toml;

$toml_data = Toml::parse('test.toml');
var_dump($toml_data);

実行してみる

$ php sample.php
Array
(
    [AWS_SECRET_KEY] => 1234567890qwertyuiop
    [USE_DATABASE] => 1
    [BARTH_DAY] => DateTime Object
        (
            [date] => 1984-01-21 00:00:00.000000
            [timezone_type] => 3
            [timezone] => Asia/Tokyo
        )

    [MEMO] => データベースはMYSQLにしました。
AWSも使ってます。
SendGridとかも使いたいな。
    [COMMENT] => こんにちはKojirockです。フリーランスのエンジニアやってます。お仕事ください
    [DATABASE] => Array
        (
            [PORT] => 3306
            [USER] => kojirock
            [PASSWORD] => 1234567890qwertyuiop
            [HOST] => localhost
        )

    [FAMILY] => Array
        (
            [MYSELF] => Array
                (
                    [name] => kojirock
                )

            [WIFE] => Array
                (
                    [name] => nyoro
                )

            [SON] => Array
                (
                    [name] => yutoton
                )

        )

    [LIKE] => Array
        (
            [0] => Array
                (
                    [MUSIC] => Array
                        (
                            [0] => Array
                                (
                                    [name] => エリック・クラプトン
                                )

                            [1] => Array
                                (
                                    [name] => モンパチ
                                )

                        )

                    [FOOD] => Array
                        (
                            [0] => Array
                                (
                                    [name] => ラーメン
                                )

                        )

                    [MOVIE] => Array
                        (
                            [0] => Array
                                (
                                    [name] => バック・トゥ・ザ・フューチャー
                                )

                        )

                )

        )

)

php5系でも問題ないみたいですね。

レガシーな環境でもなんとか使えそうです。

4. Tomlファイル作ってみる

パーサだけではなく、ビルダーもあるみたいです。

今回作成した test.toml と同じ内容のデータを1から作成してみます。

sample_2.php

<?php
require_once './vendor/autoload.php';

use Yosymfony\Toml\TomlBuilder;

$builder = new TomlBuilder();
$results = $builder->addValue("AWS_SECRET_KEY", "1234567890qwertyuiop", "AWSのシークレットキー")
            ->addValue("USE_DATABASE", true, "データベースを使用するかどうか")
            ->addValue("BARTH_DAY", new \Datetime('1984-01-21'), "誕生日")

            ->addComment("簡易メモ")
            ->addValue("MEMO", "データベースはMYSQLにしました。\nAWSも使ってます。\nSendGridとかも使いたいな。")

            ->addComment("コメント")
            ->addValue("COMMENT", "こんにちはKojirockです。フリーランスのエンジニアやってます。お仕事ください")

            ->addComment("データーベース設定")
            ->addTable("DATABASE")
                ->addValue("PORT", 3306)
                ->addValue("USER", "kojirock")
                ->addValue("PASSWORD", "1234567890qwertyuiop")
                ->addValue("HOST", "localhost")

            ->addComment("家族構成")
            ->addTable("FAMILY.MYSELF")
                ->addValue("name", "kojirock")
            ->addTable('FAMILY.WIFE')
                ->addValue("name", "nyoro")
            ->addTable('FAMILY.SON')
                ->addValue("name", "yutoto")

            ->addComment("好きなもの")
            ->addArrayTables("LIKE")
                ->addArrayTables('LIKE.MUSIC')
                    ->addValue("name", "エリック・クラプトン")
                ->addArrayTables('LIKE.MUSIC')
                    ->addValue("name", "モンパチ")

                ->addArrayTables('LIKE.FOOD')
                    ->addValue("name", "ラーメン")

                ->addArrayTables('LIKE.MOVIE')
                    ->addValue("name", "バック・トゥ・ザ・フューチャー")

            ->getTomlString();
print_r($results);

実行してみる

$ php sample_2.php
AWS_SECRET_KEY = "1234567890qwertyuiop" #AWSのシークレットキー
USE_DATABASE = true #データベースを使用するかどうか
BARTH_DAY = 1984-01-21T00:00:00Z #誕生日
#簡易メモ
MEMO = "データベースはMYSQLにしました。\nAWSも使ってます。\nSendGridとかも使いたいな。"
#コメント
COMMENT = "こんにちはKojirockです。フリーランスのエンジニアやってます。お仕事ください"
#データーベース設定

[DATABASE]
PORT = 3306
USER = "kojirock"
PASSWORD = "1234567890qwertyuiop"
HOST = "localhost"
#家族構成

[FAMILY.MYSELF]
name = "kojirock"

[FAMILY.WIFE]
name = "nyoro"

[FAMILY.SON]
name = "yutoto"
#好きなもの

[[LIKE]]

[[LIKE.MUSIC]]
name = "エリック・クラプトン"

[[LIKE.MUSIC]]
name = "モンパチ"

[[LIKE.FOOD]]
name = "ラーメン"

[[LIKE.MOVIE]]
name = "バック・トゥ・ザ・フューチャー"

流石に完全に一緒というわけにはいけませんが、それっぽい内容になったみたいです。

5. test_2.tomlを作成して確認する

この内容を test_2.toml という名前で保存して、最初に作成した test.toml の出力と同じか確認してみます。

test_2.tomlを作成

AWS_SECRET_KEY = "1234567890qwertyuiop" #AWSのシークレットキー
USE_DATABASE = true #データベースを使用するかどうか
BARTH_DAY = 1984-01-21T00:00:00Z #誕生日
#簡易メモ
MEMO = "データベースはMYSQLにしました。\nAWSも使ってます。\nSendGridとかも使いたいな。"
#コメント
COMMENT = "こんにちはKojirockです。フリーランスのエンジニアやってます。お仕事ください"
#データーベース設定

[DATABASE]
PORT = 3306
USER = "kojirock"
PASSWORD = "1234567890qwertyuiop"
HOST = "localhost"
#家族構成

[FAMILY.MYSELF]
name = "kojirock"

[FAMILY.WIFE]
name = "nyoro"

[FAMILY.SON]
name = "yutoto"
#好きなもの

[[LIKE]]

[[LIKE.MUSIC]]
name = "エリック・クラプトン"

[[LIKE.MUSIC]]
name = "モンパチ"

[[LIKE.FOOD]]
name = "ラーメン"

[[LIKE.MOVIE]]
name = "バック・トゥ・ザ・フューチャー"

sample_3.phpを作成

<?php
require_once './vendor/autoload.php';

use Yosymfony\Toml\Toml;

$toml_data = Toml::parseFile('test_2.toml');
print_r($toml_data);

実行してみる

$ php sample_3.php
Array
(
    [AWS_SECRET_KEY] => 1234567890qwertyuiop
    [USE_DATABASE] => 1
    [BARTH_DAY] => DateTime Object
        (
            [date] => 1984-01-21 00:00:00.000000
            [timezone_type] => 2
            [timezone] => Z
        )

    [MEMO] => データベースはMYSQLにしました。
AWSも使ってます。
SendGridとかも使いたいな。
    [COMMENT] => こんにちはKojirockです。フリーランスのエンジニアやってます。お仕事ください
    [DATABASE] => Array
        (
            [PORT] => 3306
            [USER] => kojirock
            [PASSWORD] => 1234567890qwertyuiop
            [HOST] => localhost
        )

    [FAMILY] => Array
        (
            [MYSELF] => Array
                (
                    [name] => kojirock
                )

            [WIFE] => Array
                (
                    [name] => nyoro
                )

            [SON] => Array
                (
                    [name] => yutoto
                )

        )

    [LIKE] => Array
        (
            [0] => Array
                (
                    [MUSIC] => Array
                        (
                            [0] => Array
                                (
                                    [name] => エリック・クラプトン
                                )

                            [1] => Array
                                (
                                    [name] => モンパチ
                                )

                        )

                    [FOOD] => Array
                        (
                            [0] => Array
                                (
                                    [name] => ラーメン
                                )

                        )

                    [MOVIE] => Array
                        (
                            [0] => Array
                                (
                                    [name] => バック・トゥ・ザ・フューチャー
                                )

                        )

                )

        )

)

test.tomlと内容は一緒でした!

終わりに

初tomlでしたが、色々出来て面白かったです。

参考サイトでも言われていますが、JSONと非常に似ているなと感じました。

最近は設定ファイル系の管理はdotenvでやってたのですが、これを気にtomlに乗り換えるのも有りかと思いました。

お疲れ様でしたー。