LoginSignup
1
0

More than 1 year has passed since last update.

LaravelでYamlファイルを簡単に扱う方法

Posted at

はじめに

何かといろいろな活用法があるYamlファイル。この記事では、Laravelで指定ディレクトリ以下のYamlファイルを読み取り、配列に変換したうえで取得する方法について解説します。

使用ライブラリ

  • symfony/yaml

動作確認環境

  • PHP-8.0
  • Laravel-8.0

インストール

以下は開発環境でのみYamlファイルを使用する場合のインストール方法です。
本番環境でも使用する想定がある場合は--devを外して下さい。

composer require --dev symfony/yaml

サンプルコード

下記クラスをコンストラクトインジェクションする。またはクラスをmakeして下さい。
なお、ネームスペースは適時変更下さい。

Reader.php
<?php

namespace Hogehoge;

use File;
use Illuminate\Filesystem\Filesystem;
use LogicException;
use Symfony\Component\Yaml\Yaml;

/**
 * Class Reader
 */
class Reader
{
    /**
     * @var \Symfony\Component\Yaml\Yaml
     */
    protected $yaml;

    /**
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $file;

    /**
     * YamlFileOperation constructor.
     */
    public function __construct(
        Filesystem $file,
        Yaml $yaml
    ) {
        $this->yaml = $yaml;
        $this->file = $file;
    }

    /**
     * Read yaml files.
     *
     * @param  string  $directoryPath
     * @param  array  $exceptFileNames
     * @return array
     */
    public function readFileByDirectoryPath(string $directoryPath, array $exceptFileNames = []): array
    {
        $yamlFiles = $this->readByDirectoryPath($directoryPath);

        // Exclude from creation
        if (! empty($exceptFileNames) && ! empty($yamlFiles)) {
            $yamlFiles = collect($yamlFiles)->filter(function ($value, $key) use ($exceptFileNames) {
                return ! in_array(basename($key, '.yml'), $exceptFileNames, false);
            })->all();
        }

        return $yamlFiles;
    }

    /**
     * Read yaml files.
     *
     * @param  string  $directoryPath
     * @param  string  $findFileName
     * @return array
     */
    public function readFileByFileName(string $directoryPath, string $findFileName): array
    {
        $yamlFiles = $this->readFileByDirectoryPath($directoryPath);

        foreach ($yamlFiles as $fileName => $yamlFile) {
            if (basename($fileName, '.yml') === $findFileName) {
                return $yamlFile;
            }
        }

        return [];
    }

    /**
     * Reading definition data.
     *
     * @param  string  $targetDirectoryPath
     * @return array
     */
    protected function readByDirectoryPath(string $targetDirectoryPath): array
    {
        if (! $this->file->isDirectory($targetDirectoryPath)) {
            throw new LogicException($targetDirectoryPath.': read path must be a directory');
        }

        $filePaths = $this->getAllFilePath($targetDirectoryPath);

        return $this->parseAllYaml($filePaths);
    }

    /**
     * Recursively get a list of file paths from a directory.
     *
     * @param  string  $directoryPath
     * @return array
     */
    protected function getAllFilePath(string $directoryPath): array
    {
        $filePaths = [];

        if (! $this->file->isDirectory($directoryPath)) {
            throw new LogicException('Not a Directory');
        }

        $files = $this->file->allFiles($directoryPath);
        foreach ($files as $file) {
            $realPath = (string) $file->getRealPath();
            $filePaths[$realPath] = $realPath;
        }

        return $filePaths;
    }

    /**
     * Parse all definition Yaml files.
     *
     * @param  array  $filePaths
     * @return mixed
     */
    protected function parseAllYaml(array $filePaths): array
    {
        $yamlParseTexts = [];

        foreach ($filePaths as $filePath) {
            if (count($this->parseYaml($filePath)) >= 2) {
                throw new LogicException('Yaml data must be one data per file filePath: '.$filePath);
            }

            // Rule that there is always one data in Yaml data
            $yamlParseTexts[$filePath] = collect($this->parseYaml($filePath))->first();
        }

        return $yamlParseTexts;
    }

    /**
     * Parse Yaml files.
     *
     * @param  string  $filePath
     * @return mixed
     */
    protected function parseYaml(string $filePath)
    {
        $extension = $this->file->extension($filePath);
        if ($extension !== 'yml') {
            throw new LogicException('Could not parse because it is not Yaml data filePath: '.$filePath);
        }

        return $this->yaml::parse(file_get_contents($filePath));
    }
}

使い方

Reader.php
$yamlReader = app()->make(Reader::class);

$result = $yamlReader->readFileByDirectoryPath('yamlが保存されているディレクトリパス', ['除外したいファイル名']);

$result2 = $yamlReader->readFileByFileName('yamlが保存されているディレクトリパス', '読み込みたいファイル名');

関連

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0