ブログ
【Laravel】コマンドの作成について
はじめまして、2021年4月に入社いたしましたT.Uです。
今回はLaravelのコマンド作成について記事を書きたいと思います。
業務の中で以下の要件を満たす必要がありました。
- ステージング環境のデータベースに入っているデータを開発環境で確認可能にする
- データの整形を行うため、CSV形式でデータ出力を可能にする
PostgreSQLの場合、以下のコマンドでSQLのクエリー結果をCSVに出力することは可能ですが、何度も行う場合はとても面倒に思います。
psql 接続情報など -c "SELECT * FROM users;" -A -F, > output.csv
そこで、コマンドを作成しデータベース上のデータをCSV出力できるようにしたので、備忘録も兼ねてLaravelでのコマンド作成についてまとめたいと思います。
コマンドの作成
まずは、サンプルとして簡単なコマンドを作成し説明します。
コマンドを実行し、新しいコマンドクラスを作成します。
作成が完了すると、app/Console/Commands
配下にファイルが生成されます。
php artisan make:command SampleCommand
各プロパティとメソッドについて
ここからは先ほど作成したapp/Console/Commands/SampleCommand.php
を編集していきます。
signatureプロパティ
signatureプロパティには、コマンドの名前や使い方を記述します。
protected $signature = 'command:sample-command {message=Hello World : メッセージを指定}';
descriptionプロパティ
php artisan list
を実行した際に表示される説明文を記述します。
protected $description = '引数で渡されたメッセージを表示するコマンド';
また、ヘルプを表示する際にも表示されます。
handleメソッド
コマンドが実行された時に行う処理を記述します。
public function handle()
{
$message = $this->argument('message');
$this->info($message);
}
上記のようにhandle()
に記述し、コマンドを実行した場合以下のように出力されます。
# php artisan command:sample-command
Hello World.
# php artisan command:sample-command こんにちは
こんにちは
データベースのバックアップコマンドを作成する
コマンドクラスを作成
クラス名は、DatabaseDumpCommand
としてコマンドクラスを作成します。
php artisan make:command DatabaseDumpCommand
signatureプロパティとdescriptionプロパティを編集
protected $signature = 'database:database-dump {--zip}';
protected $description = 'データベースをバックアップするコマンド';
signatureプロパティで指定した{--zip}
はコマンドを実行する際に、引数の指定がある場合はtrue
、ない場合はfalse
が取得できます。
# php artisan database:database-dump
false
# php artisan database:database-dump --zip
true
handleメソッドを編集
public function handle()
{
# zipをオプション引数として受け取る
$isZip = $this->option('zip');
# 現在の日時を取得
$carbonNow = Carbon::now();
$outputTimestamp = $carbonNow->format('Ymd_Hi');
# テーブルの一覧を取得
$tables = DB::connection()->getDoctrineSchemaManager()->listTableNames();
# 出力先のディレクトリを定義
$basePath = sprintf("%s/backup/", storage_path());
$outputPath = sprintf("%s/backup/%s/", storage_path(), $outputTimestamp);
$zipPath = sprintf("%s/backup/zip/", storage_path());
$zipFilePath = sprintf("%s%s.zip", $zipPath, $outputTimestamp);
# 出力先のディレクトリが存在しない場合はディレクトリを作成
if (!File::exists($basePath)) File::makeDirectory($basePath);
if (!File::exists($outputPath)) File::makeDirectory($outputPath);
if (!File::exists($zipPath)) File::makeDirectory($zipPath);
foreach ($tables as $table) {
# 出力先のCSVファイル名を定義
$outputFilePath = sprintf("%s%s.csv", $outputPath, $table);
# テーブルからすべてのデータを取得
$data = DB::table($table)->get();
# CSVファイルを生成
$handle = fopen($outputFilePath, 'w');
foreach ($data as $key => $row) {
# 1件目の場合はkey値をCSVヘッダーを出力する
if ($key === 0) {
$keys = collect($row)->keys()->all();
fputcsv($handle, $keys);
}
# key valueで入っているため、valueを取得する
$values = collect($row)->values()->all();
fputcsv($handle, $values);
}
fclose($handle);
}
$this->info('CSVファイルを作成しました');
# コマンドライン引数としてzipが渡されている場合はZIPファイルを生成する
if ($isZip) {
# CSVファイルの一覧を取得
$files = File::files($outputPath);
# ZipArchiveインスタンスを生成
$zip = new ZipArchive;
if ($zip->open($zipFilePath, ZipArchive::CREATE) === true) {
# CSVファイルをZIPに追加
foreach ($files as $file) {
$zip->addFile($file->getPathname(), $file->getFilename());
}
$zip->close();
$this->info('ZIPファイルを作成しました');
} else {
$this->warn('ZIPファイルの作成に失敗しました');
}
}
}
作成したコマンドを実行
コマンドを実行すると、storage/backup/
にCSVとZIPファイルが生成されていることを確認できます。
# php artisan database:database-dump
CSVファイルを作成しました
# php artisan database:database-dump --zip
CSVファイルを作成しました
ZIPファイルを作成しました
まとめ
Laravelでのコマンド作成について紹介しました。
今回作成したコマンドを使うことで、簡単にデータを出力することが可能になったため、データの確認作業がとても楽になりました。
また、今回紹介した入力の取得以外にも、confirmメソッド(「はい」か「いいえ」の確認)やchoiceメソッド(選択肢から選択)など様々な入力や出力をする際に便利なメソッドがあります。
また、タスクスケジューリングを利用することで、作成したコマンドを定期的に実行することも可能です。
株式会社ウイングドアは福岡のシステム開発会社です。
現在、私達と一緒に"楽しく仕事が出来る仲間"として、新卒・中途採用を絶賛募集しています!
ウイングドアの仲間達となら楽しく仕事できるかも?と興味をもった方、
お気軽にお問い合わせ下さい!