20210128のlaravelに関する記事は8件です。

LaravelでDBのテーブルやカラムの編集をしてみた

はじめに

laravelを使いDBのテーブルやカラムを作成したり削除、追加などをしてみたので備忘録として書きました。お役に立てれば幸いです。

間違い等がございましたら、ご指摘のほどよろしくお願い致します。(お手柔らかにお願いします...)

目次

  • 開発環境
  • マイグレーションについて
  • DB接続の確認
  • マイグレーションファイルの作成
  • カラム構成の編集
  • マイグレーションファイルの実行
  • カラムの追加
  • カラム名の変更
  • カラムの削除
  • ロールバック
  • リセット
  • リフレッシュ
  • カラムのデータ型の変更
  • 参考文献

開発環境

MAMP
MySQL 5.7
laravel 6.0
php 7.4

マイグレーションについて

マイグレーションとは
PHPフレームワーク内でのスクリプトを用いてデータベース情報を管理していく事です。
マイグレーションは基本的にLaravelのスキーマビルダ(Schema)と一緒に使い、アプリケーションのデータベーススキーマを作成するために使用します。また、後からカラムを追加したり一つ前の状態のデータに戻すこともできます。

ちなみに、LaravelのSchemaファサードは、テーブルの作成や操作をサポートしてるデータベースシステム全部に対しサポートします。

ファサードについては下記の記事がとても分かりやすかったので覗いてください。
https://qiita.com/yousan/items/18dab4dbac4a27ce3662

注意マイグレーション機能の導入前に、LaravelがDBに接続出来ている事が最低限必要なので、接続していない場合は、.envファイルを開いて接続情報を記載してください。

MySQL
DB_CONNECTION=mysql
DB_HOST=127.0.0.1     # ホスト名
DB_PORT=3306          # ポート番号
DB_DATABASE=###       #データベース名
DB_USERNAME=###       # ユーザ名
DB_PASSWORD=###       # パスワード

マイグレーションファイルの作成

$ php artisan make:migration create_[テーブル名]_table  --create=[テーブル名]

上記のように、Artisanコマンドを使って実行すると、Database/migrationsにマイグレーションファイルが作られます。
今回は本のデータに関するテーブルを作成しようと思うので、php artisan make:migration crete_books_table --create=booksを実行してみたいと思います。

このコマンドを実行する際に気をつけて欲しい点があります。

  • 作成するマイグレーションファイルですが、基本的には作成するテーブル1つにつき1つのマイグレーションファイルを作成します。

  • create__tableの箇所は書かなくても良いですが、何の為のファイルかを一目で分かるように書いておくのが無難です。(laravelの公式の書き方に倣っています)

  • crete_books_tableのように、テーブル名は複数形で作るようにしましょう。理由は、ここで記述した名前(books)がそのままテーブル名になるからです。

  • ここでの名前は、生成するマイグレーションファイルのクラス名に反映されるので、そのことを考慮した上で名前をつけましょう。

また、make:migrationコマンドには--createオプション引数が用意されています。
--createオプションは、Schemaクラスのメソッド(テーブルを新たに作成するcreateメソッド)を指定しています。つまり、テーブルを新たに作成するマイグレーションファイルを作成するコマンドの実行時に指定するオプションです。

$ php artisan make:migration create_books_table --create=books(テーブル名)
と記述すると、Schemaファサードのcreateメソッドを指定できる

上記の注意点を踏まえて生成されたマイグレーションファイルを見てみると、下記の様な構成でファイルが作られています。ざっくりと説明するとpublic function up(){}でテーブルのカラム構成を決め、public function down(){}で作成したテーブルを崩す役割を担っています。(間違っていればご指摘ください)

2021_01_28_121411_crete_books_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreteBooksTable extends Migration
{//クラス名に注目してください。先ほど述べたようにクラス名に反映されいています。
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('books');
    }
}

それぞれの役割を詳しく見ていきます。

カラム構成の編集(public function up(){};)

public function up()
{
 Schema::create('books', function (Blueprint $table) {
       $table->bigIncrements('id');
       $table->string('title',200);
       $table->string('name',100);
       $table->string('comment',200);
       $table->integer('price');
       $table->timestamps();
    });
}

上述で使用している、Schema::createがSchemaファサードのcreateメソッドであり、新しいデータベーステーブルを作成する際に使用します。$table->string();などはスキーマビルダと呼ばれていて、テーブルを構築する時に使用するさまざまなカラムタイプを指定できます。
Laravelのマイグレーションファイルではstringやinteger以外にも指定できるデータ型があるので、学習時によく使用した(今後も使用するであろう)ものを下記に一覧表で記載しておきます。

カラムタイプ一覧

コマンド 説明
$table->bigIncrements('id'); 符号なし、BIGINTを使用したオートインクリメント(自動増分)ID(主キー)
$table->boolean('confirmed'); BOOLEANカラム
$table->char('name', 100); オプションの文字長を指定するCHARカラム
$table->date('created_at'); DATEカラム
$table->text('description'); TEXTカラム
$table->timestamps(); NULL値可能なcreated_atとupdated_atカラム追加
$table->ipAddress('visitor'); IPアドレスカラム
$table->integer('votes'); INTEGERカラム
$table->json('options'); JSONフィールド

また、Laravelではカラムに装飾子を付け加えることができます。
先ほど解説した記述文にそのまま -> (アロー演算子)で繋げて記述するだけです。

$table -> string('email') -> unique();
//メールアドレスの重複をなくす
$table -> string('email') -> unique() -> nullable();
//カラムにnullを設定できるようにする

装飾子一覧

装飾子 説明
->autoIncrement() 整数カラムを自動増分ID(主キー)へ設定
->after('column') 指定カラムの次に他のカラムを設置(MySQLのみ)
->charset('utf8') カラムへキャラクタセットを指定(MySQLのみ)
->collation('utf8_unicode_ci') カラムへコロケーションを指定(MySQL/SQL Serverのみ)
->comment('my comment') カラムにコメント追加(MySQL/PostgreSQLのみ)
->default($value) カラムのデフォルト(default)値設定
->first() カラムをテーブルの最初(first)に設置する(MySQLのみ)
->nullable($value = true) デフォルトで)NULL値をカラムに挿入する
->storedAs($expression) stored generatedカラムを生成(MySQLのみ)
->useCurrent() TIMESTAMPカラムのデフォルト値をCURRENT_TIMESTAMPに指定
->unsigned() 整数カラムを符号なしに設定(MySQLのみ)
->virtualAs($expression) virtual generatedカラムを生成(MySQLのみ)

マイグレーションファイルの実行

$ php  artisan migrate

上記のコマンドを実行すると、マイグレーションファイルに設定された形でテーブルが作られます。

また、テーブルを作成するとidにunsignedという属性が付与され、意味は符号なし、マイナスの値は存在しないと示しています。

今回の記事では、リレーションを使いませんが、リレーションを組むときに、親テーブルと子テーブルとの間でマイナス値があったりなかったりするとエラーが発生するので、予めマイグレーションファイルでカラムの詳細を決める時に、下記のように指定することでマイナス値を排除しておくことをオススメします。

 $table->tinyInteger('book_id')->unsigned();
//or
$table->unsignedTinyInteger('book_id');

また、migrateコマンドには上記の設定を反映するコマンド以外にも、様々な操作を行えます。
では、

  1. カラムの追加
  2. カラム名の変更
  3. カラムの削除
  4. ロールバック
  5. リセット
  6. リフレッシュ
  7. カラムのデータ型の変更

の操作について触れてみたいと思います。

カラムの追加

基本的に、カラムの追加や編集をする場合は、上記で作成したマイグレーションファイルを編集し、下記のようにphp artisan migrate:refreshを付けて再度マイグレーションを実行します。

$ php artisan migrate:refresh

しかし、私は変更した過程をマイグレーションファイルとして記録しておきたいので、tableオプションに変更するテーブル名を指定し、新たにマイグレーションファイルを作成しています。
従って、この記事では、新しいマイグレーションファイルを作りつつテーブルを変更しています。

今回作成したテーブルに出版社名のカラムを追加してみたいと思います。

新たにカラムを追加する際は、

$  php artisan make:migration add_publisher_to_books_table --table=books

のように記述します。作成時との変更点は、オプション引数が--table=テーブル名になっている点と、add_publisher_to_books_tableの2つです。

  • --tableは、テーブル構造を変更する場合の決まり文句みたいなものです。追加する際は、記述してください。

  • add_publisher_to_books_tableは、database/migrations下で作られたファイルの中でクラス名としても使われるので、何故、そのファイルが作成されたのかを一目で分かるように変更しています。

上記のコマンドを実行すると、下記のようなファイルが作成されます。

2021_01_28_122256_add_publisher_to_books_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddPublisherToBooksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('books', function (Blueprint $table) {
            //新規作成時はSchema::create
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('books', function (Blueprint $table) {
            //
        });
    }
}

マイグレーションファイルが作成されたら、public function up(){}に追加するカラムを記述します。

public function up()
{
Schema::table('books', function (Blueprint $table)
{
 $table->string('publisher',50)->after('title');
/*$table->string('publisher',50);の場合、カラムの最後に追加されるので、
追加したい順を決める場合、->after('カラム名');と指定することで
指定したカラム名の次に追加される*/
  });
}

追加するカラムの記述が終わり次第、php artisan migrateを実行するとカラムが追加される。

カラム名の変更

まず、設定として

$ composer require doctrine/dbal

とコマンドを入力して、composerで"doctrine/dbal"をインストールして下さい。laravelはデフォルトでカラム名の変更や削除ができません。(何でや...調べてみます)

注意上記のコマンド入力後、エラーが発生する場合

$ composer require "doctrine/dbal:2.*"

のように記述して下さい。理由は、下記リンクの記事が分かりやすかったので覗いてください。

[laravel] doctrine/dbalを入れたのに「Class 'Doctrine\DBAL\Driver\PDOMySql\Driver' not found」と言われる

カラム名を変更する為にはrenameColumnメソッドを使用します。

今回は、booksテーブルのnameカラムをauthorに変更します。

下記のようにマイグレーションファイルを作成します

$ php artisan make:migration rename_変更前のカラム名_変更後のカラム名_テーブル名_table --table=テーブル名

と記述する。

$ php artisan make:migration rename_name_author_books_table --table=books

実行すると、下記のようにマイグレーションファイルが作成され、public function up(){}renameColumnメソッドを使い、変更したいカラム名を指定する。その後、php artisan migrateコマンドを実行することで変更が反映される。

    public function up()
    {
        Schema::table('books', function (Blueprint $table) {
        $table->renameColumn('name','author');
//$table->renameColumn('変更する前のカラム名', '変更した後のカラム名');
        });
    }

カラムの削除

カラムを削除する為には、dropColumnメソッドを使用します。

毎度お馴染みのようにマイグレーションファイルを作成します。

$ php artisan make:migration drop_削除するカラム名_テーブル名_table --table=テーブル名

今回は下記のようにコマンドを使います。

$ php artisan make:migration drop_comment_books --table=books

コマンドを実行後、マイグレーションファイルが作成され、下記のようにpublic function up(){}dropColumnメソッド使い、削除するカラムを指定する。その後、php artisan migrateコマンドを実行することで変更が反映される。

    public function up()
    {
        Schema::table('books', function (Blueprint $table) {
            $table->dropColumn('comment');
          //$table->dropColumn('削除したいカラム名');
        });
    }

ロールバック

カラムを追加したがやっぱり一つ前に戻りたい、migrateの状態を一つ前に戻す場合にロールバックコマンドを使います。正確に言えばマイグレーションファイルのdown()に記述された処理を実行していきます。

$ php artisan migrate:rollback
//1つ前の状態に戻る

上記のコマンドは、stepオプションをつけることによって、--step=戻りたい数を記述することで、いくつ前に戻すかを指定することができる。

$ php artisan migrate:rollback --step=2
//2つ前に戻ることになる

注意 php artisan migrate:rollbackを使う場合、追加時に作成したマイグレーションファイルで、追加したカラムをpublic function down(){}dropColumnメソッドを使い、下記のように記述する必要がある。※下記のマイグレーションファイルはロールバックを説明する為に別途作成したファイルなのでカラム名commentが重複しています。申し訳ございません。

別途作成、記事で作成したカラム(comment)とは関係ありません
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddCommentToBooksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('books', function (Blueprint $table) {
            $table->string('comment',200);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('books', function (Blueprint $table) {
            $table->dropColumn('comment');
        });
    }
}

php artisan migrate:rollbackを実行後、php artisan migrate:statusで状態を確認すると、下記のようにカラムcommentが追加される前の状態に戻っている。

Ran? Migration Batch
Yes 2014_10_12_000000_create_users_table 1
Yes 2014_10_12_100000_create_password_resets_table 1
Yes 2019_08_19_000000_create_failed_jobs_table 1
Yes 2021_01_27_203453_create_posts_table 1
Yes 2021_01_27_203607_create_comments_table 1
Yes 2021_01_28_121411_crete_books_table 1
Yes 2021_01_28_174256_add_publisher_to_books_table 2
Yes 2021_01_28_185459_rename_name_author_books_table 3
No 2021_01_28_211805_add_comment_to_books_table 9

リセット

$ php artisan migrate:reset

上記のコマンドで、今まで行ったマイグレーションを全てロールバックし初期状態のデータベースに戻します。正確に言えばマイグレーションファイルのdown()に記述された処理を実行していきます。
ロールバックとの違いは、存在するすべてのマイグレーションファイルのdown()が実行される点です。

リフレッシュ

$ php artisan migrate:refresh

上記のコマンドで、全てのマイグレーションをリセットし初期状態に戻した後、migrateコマンドを行います。
また、リフレッシュもロールバックと同じように、stepオプションをつけることによって、指定した回数分だけ戻ってmigrateすることができます。
php artisan migrate:refreshは、php artisan migrate:resetしてmigrateするのと同じです。

カラムのデータ型の変更

booksテーブルのcommentカラムをsrting型からtext型に変更してみます。

コマンドは下記のように記述してマイグレーションファイルを作成します。

$ php artisan make:migration change_comment_books --table=books

マイグレーションファイルでは、public function up(){}changeメソッドを使い、カラムのデータ型を変更しています。

    public function up()
    {
        Schema::table('books', function (Blueprint $table) {
            $table->text('comment')->change();
        });
    }

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS - C9でLaravel / Nuxt.jsを構築する備忘録

毎回調べるのが面倒なので、未来の自分へ備忘録です。
順番に実行したら構築出来るわけではありません。

今回構成する内容
・バックエンド:laravel 6系
・フロントエンド:vue.js nuxt.js vuetify

composerのインストール

brew install composer

終わったら念のため-vでバージョン確認。

laravelのインストール

composer create-project --prefer-dist laravel/laravel app_name "6.*"

このコマンドでは何故かvenderファイル、envファイルが作成されなかった。

インストールされているphpパッケージのバージョン確認

yum list installed | grep php

このコマンドで確認出来た古いパッケージの削除

sudo yum erase -y hogehoge

補足:-yは全ての問い合わせに対してYESで返す。

yumのアップグレード

sudo yum upgrade
sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm

パッケージインストール

sudo yum install -y php73 php73-php-pdo php73-php-mbstring php73-php-xml

補足:うるおぼえだが、laravelは確か7.3以降のphpが必要なはず

PHPコマンドを使えるようにする

$which php73
/usr/bin/php73
$alias php='/usr/bin/php73'

補足:whichコマンドでどこにファイルがあるのか調べる。その後aliasコマンドでphpと入力したときの呼び出し先を設定する。

composerコマンドを使えるようにする

sudo ln -s /usr/bin/php73 /usr/bin/php
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS - C9でLaravel / Nuxt.jsの環境構築に関する備忘録

毎回調べるのが面倒なので、未来の自分へ備忘録です。
順番に実行したら構築出来るわけではありません。

今回構成する内容
・バックエンド:laravel 6系
・フロントエンド:vue.js nuxt.js vuetify

composerのインストール

brew install composer

終わったら念のため-vでバージョン確認。

laravelのインストール

composer create-project --prefer-dist laravel/laravel app_name "6.*"

このコマンドでは何故かvenderファイル、envファイルが作成されなかった。

インストールされているphpパッケージのバージョン確認

yum list installed | grep php

このコマンドで確認出来た古いパッケージの削除

sudo yum erase -y hogehoge

補足:-yは全ての問い合わせに対してYESで返す。

yumのアップグレード

sudo yum upgrade
sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm

パッケージインストール

sudo yum install -y php73 php73-php-pdo php73-php-mbstring php73-php-xml

補足:うるおぼえだが、laravelは確か7.3以降のphpが必要なはず

PHPコマンドを使えるようにする

$which php73
/usr/bin/php73
$alias php='/usr/bin/php73'

補足:whichコマンドでどこにファイルがあるのか調べる。その後aliasコマンドでphpと入力したときの呼び出し先を設定する。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laradocを使用した環境構築を例にdockerの使い方を整理する

本記事の目的

本記事の目的は、dockerを学習したが、期間が開いてもすぐに使用できるよう記憶を定着させるためである。(dockerを使用した環境構築において、普段常にdockerを使用するわけではなく、期間が開くと忘れてしまっていた。)
Docker関連を読み直すだけでは頭に入らない。

今回は、Laravelの開発においてLaradocを使用するが、その一般的な手順から、dockerの意味合いを整理し理解することにより記憶の定着を図りたい。

以下のようにまとめた(つもり)
◇1.laradocを使用したlaravelを動かすまでの手順
◇2.1の手順にて使用されているdockerコマンドの整理
◇3.docker-composerの整理
◇4.まとめ
◇5.その他

1.laradocを使用したlaravelを動かすまでの手順

とりあえずlaradoc初期画面まで出す手順をざっくり4ステップで記載
1.laradocをダウンロードする

$ git clone https://github.com/shonansurvivors/laradock-like.git laradock

完了するとlaradocのディレクトリ ができる。
laradocを使用すれば、laravelの開発環境を簡単に構築できる。

2.laradocディレクトリ の.env修正
環境変数を決めている。

3.laradocディレクトリ にて下記実行(例)

docker-compose up -d workspace php-fpm nginx postgres

複数のコンテナ(workspace、php-fpm、nginx、postgres)を同時に立ち上げ、コンテナをバックグランドで立ち上げている。(今回はpostgresは必要ないが記載)

4.laravelのインストール(例)

docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "5.5.*"

laradocディレクトリ の直下で実行する。コンテナworkspaceに入り、composerよりlaravelをダウンロードしている。

ブラウザでlocalhostにアクセスすると、画面が表示される。

参考にしたQiita資料
Laradockを使ってLaravelを動かすまで
Laradockでの環境構築方法2パターンを細かめに説明

2. 「1」の手順にて使用されているdockerコマンドの整理

使用しているコマンドは、docker-compose upと、docker-compose execである。
以下のステップで整理する。
1.docker-compose upとdocker-compose execの確認
2.execで行っていることの整理
3.docker-composeの意味合い

2.1 docker-compose upとdocker-compose execの確認

リファレンス https://docs.docker.jp/compose/overview.html を参照すれば良いと思うが、項目を分けて記載する。

2.1.1 docker-compose upについて

docker-composer up
コンテナをまとめて立ち上げる。-dでバックグラングで立ち上がる。
今回は必要なコンテナ(workspace、php-fpm、nginx、postgres)を選択して実行している。

2.1.2 docker-compose exec

起動中のコンテナに入ることで、今回は起動したコンテナworkspaceに入り、composerのコマンドを実行している。
docker-composeのコマンドリファレンスを見たら、execコマンドの記載がない。
Docker ドキュメントを見れば一応記載はあった。
またhelpコマンドで確認すると、下記が表示された。

$ docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  -c, --context NAME          Specify a context name
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent (DEPRECATED)
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show version information and quit

exec Execute a command in a running container
より、起動中のコンテナに入ること。

2.2 execで行っていることの整理

docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "5.5.*"

「2.1.2」でとりあえずコンテナに入って処理しているのはわかるが、久しぶりに上記コマンドを確認すると、workspaceコンテナで、laravelがでてきていまいちわからなかったので、もう少し確認する。
以下の流れで確認する。
1.composerの確認
2.workspaceでのcomposerの適用の確認

2.2.1 composerの確認

composerを使用している理由として、LaravelはComposerを依存パッケージの管理に使用しているからである。
laravelサイトより、laravelを使用するにあたり、以下の手順になる。
1.開発機にComposerを確実にインストール
2.Composerのcreate-projectコマンドを実行し、laravelをインストール

2.2.2 workspaceでのcomposerの適用の確認

$ docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "6.8.*"

workspaceのコンテナに入り、composerを実行しているが、workspaceのコンテナにcomposerをインするトールする必要があり、暗黙にそういう処理をしていることが想像できる。

コンテナ開発時に、Dockerfileを使用して、composerのインストールをしているのは予想され、その箇所を確認してみる。

./workspaceのDockerfile
FROM laradock/workspace:2.6.1-${LARADOCK_PHP_VERSION}
~省略
###########################################################################
# Composer:
###########################################################################

USER root

# Add the composer.json
COPY ./composer.json /home/laradock/.composer/composer.json

# Add the auth.json for magento 2 credentials
COPY ./auth.json /home/laradock/.composer/auth.json

# Make sure that ~/.composer belongs to laradock
RUN chown -R laradock:laradock /home/laradock/.composer

# Export composer vendor path
RUN echo "" >> ~/.bashrc && \
    echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.bashrc

USER laradock

# Check if global install need to be ran
ARG COMPOSER_GLOBAL_INSTALL=false
ENV COMPOSER_GLOBAL_INSTALL ${COMPOSER_GLOBAL_INSTALL}

RUN if [ ${COMPOSER_GLOBAL_INSTALL} = true ]; then \
    # run the install
    composer global install \
;fi

# Check if auth file is disabled
ARG COMPOSER_AUTH=false
ENV COMPOSER_AUTH ${COMPOSER_AUTH}

RUN if [ ${COMPOSER_AUTH} = false ]; then \
    # remove the file
    rm /home/laradock/.composer/auth.json \
;fi

ARG COMPOSER_REPO_PACKAGIST
ENV COMPOSER_REPO_PACKAGIST ${COMPOSER_REPO_PACKAGIST}

RUN if [ ${COMPOSER_REPO_PACKAGIST} ]; then \
    composer config -g repo.packagist composer ${COMPOSER_REPO_PACKAGIST} \
;fi

# Export composer vendor path
RUN echo "" >> ~/.bashrc && \
    echo 'export PATH="~/.composer/vendor/bin:$PATH"' >> ~/.bashrc

###########################################################################
# Non-root user : PHPUnit path
###########################################################################

# add ./vendor/bin to non-root user's bashrc (needed for phpunit)
USER laradock

RUN echo "" >> ~/.bashrc && \
    echo 'export PATH="/var/www/vendor/bin:$PATH"' >> ~/.bashrc
省略~

行っていることはcomposerをインストールし、workspaceで使えるようにしていることだと思われる。

composerコマンドで具体的にできることは下記を参照したりした。
Composerのcreate-projectが何をやっているのか調べてみた
【Laravel入門】プロジェクト作成から起動まで

3.docker-composerの整理

1、2を通し、laradocを使用してlaravelを動く環境を作るのに、手順の意味を理解できたが、docker-composeと、それに付随して利用されるDockerfileについて得た理解を忘れぬようまとめておく。

docker-composeを使用する時は、基本的に下記3つのステップを踏む
1.コンテナを使用したアプリケーション環境を、Dockerfileに定義する。
2.アプリケーションを構成するサービスをdocker-compose.yml内に定義する。
こうすることで各サービスは独立した環境において起動することになる。
3.最後にdocker-compose upを実行したら、Composeはアプリケーション全体を起動・実行する。
(リファレンス https://docs.docker.jp/compose/overview.html をほぼ抜粋。)

つまり、docker-composeは、複数のコンテナを定義し実行するDocker アプリケーションのためのツール。docker-compose.ymlのファイルがある直下のディレクトリで実行する。
手順1-3の場合、使用したコンテナだけとりあげると、以下のような構成になっている。

.
├── docker-compose.yml
├── nginx
├── php-fpm
├── postgres
└── workspace
docker-compose.yml
version: '3'
services:
    workspace:
      build:
        context: ./workspace
      省略
    postgres:
      build: ./postgres
      省略
    php-fpm:
      build:
        context: ./php-fpm
      省略
    nginx:
      build:
        context: ./nginx
      省略 

docker-composer.ymlファイルのserveicesのworkspace、postgres、php-fpm、nginxがコンテナである。
docker-compose up によって、上記4つのコンテナが立ち上がる。
それぞれのコンテナは、build:のcontext:に記載ある箇所のDockerfileによってイメージが作成される。

まとめ(感想)

今回はdocker-composeとDockerfileの使用方法をざっと整理した。
dockerコマンドを手広く応用できるよう整理したかったが、本件のテーマで整理すると、docker-composeとDockerfileの理解を軸に進めた。
深堀するとdocker以外のことで不明点がボロボロ出て、逆にその確認で時間を要した。

その他

docker諸々を思い出すために、基礎となりそうな所でメモっていたことを備忘記録として残ししておく。
本記載においては、主に以下文献を使用させて頂いた。
大澤 文孝,浅居 尚. さわって学ぶクラウドインフラ docker基礎からのコンテナ構築 (Japanese Edition)

DockerEngine

DockerはLinux上で動作するソフト。Linuxに「DockerEngine」をインストールすると、Dockerのコンテナを実行できるようになる。
DockerはLinux環境で動かす以外に、Windows環境やMac環境において「DockerDesktop」というソフトを動かす方法がある。
DockerEngineをインストールしたコンピューター(=Dockerコンテナを動かすコンピューター)のことを「Dockerホスト」と呼ぶ。

Dockerイメージ

Dockerでは、コンテナ作りを支援するために、基本的なソフトやアプリケーションをインストールした「コンテナの元」が提供される。このようなコンテナの元のことを「Dockerイメージ」と言う。
Dockerイメージは、Docker社が運営しているDockerHubで公開されている。DockerHubのように、Dockerイメージを管理しているサーバーを「Dockerレジストリ」と言う。
イメージはDocker-Hubから取得するが、修正を加えたい場合の手段として、Dockerfileを作成しイメージを作ることができる。

Dockerコンテナ

イメージよりコンテナ作る。
docker run コマンドは、「docker pull」、「docker create」、「docker start」という3つの一連のコマンドをまとめて実行する利便性を重視したコマンド。

Dockerfileについて

https://knowledge.sakura.ad.jp/15253/
Dockerfileの使用の仕方は、コンテナを実行する時のカレントディレクトリに置くと、自動でDockerfileの記載に基づき実行される。
Dockerfileを使用しなければ、イメージを作成後に、コンテナで処理する作業を手作業で行う必要がある。
カスタムのDockerイメージを作るときは、手作業でファイルコピーやコマンド実行をするのではなく、Dockerfileと呼ばれる設定ファイルにファイルコピーや実行したいコマンドなど一連の設定を記述し、そのファイルを適用して作るのが一般的である。

コマンド

Dockerイメージ、Dockerコンテナはまめに確認し削除しておく。
イメージのダウンロード、コンテナ作成は簡単にでき、学習にて使用しているとどんどんたまっていき、使用マシンのレスポンスへの影響が無視できなくなる。
その関連のコマンドを記載。

・実行中のコンテナを参照する
docker ps
docker container ls

全コンテナの状態を確認する
docker ps -a

コンテナの停止、スタート、破棄
docker stop my-apache-app
docker start my-apache-app
docker rm my-apache-app

どのようなイメージをダウンロードしたか
docker image ls

Dockerイメージを削除
docker image rm httpd:2.4
docker rmi httpd:2.4

envとは何か

本件ではあまり触れなかったが、気になったのでメモっておく。
「.envファイル」だが、ladarac直下にある。
envというと、envコマンド、.envファイルがあるらしいが、
「.envファイル」は環境変数を記載し、他で使用するためのものである

env(エンブ)は Unix系オペレーティングシステム (OS) で使われるユーティリティである。環境変数のリストを出力したり、現在の環境を変えることなく異なる環境変数の下で他のコマンドを実行するのに使われる。envを使うことで、変数の追加や削除、変数の値の変更を行える。
( https://ja.wikipedia.org/wiki/Env を参照)

.envファイルの説明で下記等を参考
https://qiita.com/harutakaoka522/items/e0abddfd0311eb4fb32b

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelのFormRequestでJsonStringをValidateする

前提

Form の submit で POST を投げるのと同時に付加情報として Form データ以外の情報を JsonString の形でを追加して送る必要があったので、調べました。

PostするときのContent-typeapplication/x-www-form-urlencodedでそこにJsonStringを付加する場合なので、最初からContent-typeapplication/jsonで送信する場合は、この対応は不要でふつうにドット記法でバリデーションできると思います。

実装

Blade側

Javascriptで送信前にObjというデータをJSON化して、hiddenパラメータのjsonとして付加してSubmitします。

    <form action="{{ route('hoge.store') }}" method="post" id="form-hoge">
        {{ Form::hidden('json', null) }} // 追加
        ...
        {{ Form::text('id', null, ['class' => 'form-control']) }}
        ...
    </form>
@section('script')
<script type="module">

    ...

    // submit 前に json にデータを突っ込んで送信する
    $('#form-hoge').submit(function() {
        // 送りたいデータ
        const obj = {
            'hoge1': [
                 { 'key': 'hoge1-1', 'value': 'hoge1-1-1' },
                 { 'key': 'hoge1-2', 'value': 'hoge1-2-1' },
            ],
            'hoge2': 'hoge2-2',
            ...
        };
        $('input[name=json]').val(JSON.stringify(obj));
        return true;
    })

    ...

</script>
@endsection

FormRequest側

キモはgetValidatorInstanceで、ここで JsonString を配列化し、data_arrayという名前で FormRequest にセットします。rulesでの判定実装はセットしたdata_arrayに対しておこないます。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\Rule;

class HogePost extends FormRequest
{
    ...

    // この getValidatorInstance を override する
    protected function getValidatorInstance(): Validator
    {
        $json = $this->request->get('json');
        $this->merge(['data_array' => $json_decode($json, true)]);

        return parent::getValidatorInstance();
    }

    ...

    public function rules()
    {
        return [
            'id' => ['required', 'integer'],
            // json に Json が入ってくるかの Validation も必要
            'json' => ['required', 'json' ],
            // こういう感じで Jsonの 中身も Validate が簡単にかける
            'data_array.hoge1.*.key' => ['required', 'string', 'max:50'],
            'data_array.hoge1.*.value' => ['required', 'string', 'max:256'],
            'data_array.hoge2' => ['required', 'string', 'max:10'],
            ...
        ];
    }

    ...

Controller側

最後に引数にFormRequestを渡し、バリデーションの実行を行います。

    public function store(HogePost $request)
    {
        // バリデーションの実行
        $validated = $request->validated();

        return ...
    }

参考

https://laracasts.com/discuss/channels/laravel/form-request-validation-for-json-parameter

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PHP初心者】Laravelを2週間触ってみて理解したこと④【blade】【コンポーネント】

はじめに

こんにちはnakaです?
この記事を書いてる間にLaravelを触って3週間ほどたちました。
正しくはこうかな・・・・・・・
【PHP初心者】Laravelを2週間触ってみて理解したこと④
【PHP初心者】Laravelを3週間触ってみて理解したこと④

コンポーネント

前回のセクションと似たような機能ですが、コンポーネントは部品をテンプレ化します。書いてる自分も(゜_゜)???となってきたのでまとめます笑

ビューのファイル連携のまとめ

@include → ほかのビューをごぞっと入れ替える
@sectioin → テンプレート(親)ファイルを作成し、テンプレートと違う箇所に@yieldを使って子を読み込む
@component → 部品ごとにテンプレート化する。例えば、webサイトのヘッダーやフッター、モーダルなどに使える。(@slotというディレクティブを使う)

うーんなるほど、コンポーネントは共通のパーツを作れるって認識かな。
とりあえず動きを見てみましょう。

ちなみに前回の記事はこちら↓↓↓
【PHP初心者】Laravelを2週間触ってみて理解したこと③【blade】【継承】

コンポーネントとスロットの実装方法

今回はモーダルをコンポーネント化しましょう。Bootstrap4のモーダルを使用しています。

必要なファイルはこんな感じ

//共通パーツを作るところ
resources/views/components/modal.blade.php

// 読み込むところ
resources/views/sample.blade.php

まずはパーツを作成します。
埋め込みたい値を{{ $~~ }} とする

modal.blade.php
<div class="modal" tabindex="-1" role="dialog" id="{{ $modal_id }}">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">{{ $modal_title }}</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>{{ $modal_body }}</p>
        <p>{{ $slot }}</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">キャンセル</button>
        <button type="button" class="btn btn-primary">保存</button>
      </div>
    </div>
  </div>
</div>

表示するビューの設定です。@slot(‘変数名(componentで設定した{{$~~}})’, パラメータ) で値をコンポーネントに渡せます。
また@slot外に書いた@componentに囲まれた内容(下記でいう「slotの外に書かれた内容です。」)は{{$slot}}に出力されます。

(ややこし・・・・・(゜_゜))

sample.blade.php
@component('components.modal')
  @slot('modal_id', 'sample_modal')
  @slot('modal_title', 'sampleです')
  @slot('modal_body', '本文です。')
  @endslot
 slotの外に書かれた内容です
@endcomponent

コンポーネントの読み込んだビュー

sample.blade.php
<div class="modal" tabindex="-1" role="dialog" id="sample_modal">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">sampleです</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>本文です。</p>
        <p>slotの外に書かれた内容です。</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">キャンセル</button>
        <button type="button" class="btn btn-primary">保存</button>
      </div>
    </div>
  </div>
</div>

最後に

今回はコンポーネント化についてまとめました。
次回でbladeは最後にしようと思います;つД`)ナガカッタ
多分次の回が一番使うかな・・・・

参考文献

Laravel @extends @include コンポーネントの違いを知りたい人のために解説
【Laravel】Bladeでcomponentを利用する
componentを活用して再利用可能なviewを作成する【Laravel】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【docker初心者】phpMyadmin on dockerを使ってみた

docker環境でLaravelアプリを作成しています。
元々学習していた教材でphpMyadmin on dockerを使っていたので
自分でもできるかなと思い挑戦してみました。

こちらの記事を拝見させていただきました!
感謝です!

公式からimageをとってくる

公式サイトに行きます。
スクリーンショット 2021-01-27 20.02.01.png

上の画像のように公式のGithubに行きます。

スクリーンショット 2021-01-27 20.12.34.png

画像のようにdocker-compose.ymlのファイルを開きます。

スクリーンショット 2021-01-27 20.14.36.png

上の画像のように囲んだところのコードをコピーします。

そして自分のdocker-compose.ymlに貼ります。

docker-compose.yml
phpmyadmin:
    image: phpmyadmin
    container_name: phpmyadmin
    environment:
     - PMA_ARBITRARY=1
    restart: always
    ports:
     - 8080:80
    volumes:

これでコンテナを起動します。

ターミナル
docker-compose up -d

そしてhttp://localhost:8080にアクセスします。

スクリーンショット 2021-01-27 23.30.06.png

が、ここでデータベース名ユーザー名パスワードを入れる画面が出てきたのですが何のこっちゃって感じです。
知識なさすぎて悲しくなる。

先ほどの参考にしたサイトでは

docker-compose.yml
phpmyadmin:
  image: phpmyadmin/phpmyadmin
  environment:
    - PMA_ARBITRARY=1
    - PMA_HOST=mysql
    - PMA_USER=root
    - PMA_PASSWORD=password
  links:
    - mysql
  ports:
     - 8080:80
  volumes:
     - /sessions

となっていたのでPMA_HOST以下を編集してみましたがうまくいかず。

メンターさんに質問し解決

私の場合は

docker-compose.yml
  db:
    build: ./infra/mysql
    volumes:
      - db-store:/var/lib/mysql

となっていたので
データベース名はdb

ユーザー名パスワード

mysql/Dockerfile
MYSQL_USER= <ここ>
MYSQL_PASSWORD= <ここ>

ここに記載されていたものを入れて無事に使えるようになりました!

docker-compose.ymlは以下のように

docker-compose.yml
phpmyadmin:
    image: phpmyadmin
    container_name: phpmyadmin
    environment:
     - PMA_ARBITRARY=1
    restart: always
    ports:
     - 8080:80
    volumes:

元に戻してます。

メンターさん感謝です!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Laravel6] 条件によってバリデーションの内容を変える方法

バージョン情報

  • PHP 7.4.2
  • Laravel 6.2

実現したいこと

こんな感じのラジオボタンとテキストの入力フォームがあり、
スクリーンショット 2021-01-28 2.00.41.png

index.html
<input type="radio" name="type" value="A"><label>A</label>
<input type="radio" name="type" value="B"><label>B</label>
<br>
<input type="text" name="text">
  • Aが選択されている時は、textが整数であること
  • Bが選択されている時は、textが文字列であること
  • type, textは必ず入力されていること

こんなバリデーションをしたい。

結論

PostTextRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;

class PostTextRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'type' => 'required',
            'text' => 'required'
        ];
    }
    public function withValidator(Validator $validator)
    {
        $validator->sometimes('text', 'required | integer', function ($input) {
            return $input->type === 'A';
        });

        $validator->sometimes('file_name', 'required | string', function ($input) {
            return $input->type === 'B';
        });
    }
}

重要なところ

public function withValidator(Validator $validator)
    {
        $validator->sometimes('text', 'required | integer', function ($input) {
            return $input->type === 'A';
        });

        $validator->sometimes('file_name', 'required | string', function ($input) {
            return $input->type === 'B';
        });
    }

解説

元のコード

元々はこんな感じの記述でした。

TextController.php
public function post(Request $request)
{
    // バリデーションルールの配列を呼び出す
    $validation_rules = $this->rules();

    // typeがAかBかによってバリデーションを追加する
    if ($request->input('type') === 'A') {
        $validation_rules['text'] .= '|integer'; 
    } elseif ($request->input('type') === 'B') {
        $validation_rules['text'] .= '|string';
    }
    // バリデーション実行
    $request->validate($validation_rules);

    // postの処理...
}

protected function rules() 
{
    return [
        'text' => 'requied',
        'type' => 'requied'
    ];
}

これでも期待通りの動きはしてくれるけど、Controllerに全部書いちゃってるし、if文でバリデーションを追加するとかなんかダサい。

withValidator()というのを使うといい感じにできるらしい。

ドキュメント
参考にした記事

書き方としては、

public function withValidator(Validator $validator)
    {
        $validator->sometimes('バリデーションを行うフィールド', 'バリデーション | バリデーション', function ($input) {
            return バリデーションをする条件;
        });
    }

なので、今回のパターンに当てはめると、

PostTextRequest.php
public function withValidator(Validator $validator)
    {
        // textが整数かどうかのバリデーションを追加したい
        $validator->sometimes('text', 'required | integer', function ($input) {
            // typeがAだった時に
            return $input->type === 'A';
        });
        // textが文字列かどうかのバリデーションを追加したい
        $validator->sometimes('file_name', 'required | string', function ($input) {
            // typeがBだった時に
            return $input->type === 'B';
        });
    }
TextController.php
public function post(PostTextRequest $request)
{
    // postの処理...
}

これでControllerはスッキリするし、スマートに書ける(気がする)。

ご指摘、アドバイスお待ちしております。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む