20200209のlaravelに関する記事は21件です。

Laravel Eloquentの超基本的な使い方

自分用にまとめました

モデルの取得

主キーで取得

SELECT * FROM users WHERE id = 1 LIMIT 1;

:point_down:

App\User::find(1);

全件取得

SELECT * FROM posts WHERE writer_id = 1;

:point_down:

App\Post::where('writer_id', 1)->get();

1件だけ取得

whereの引数を配列にすれば、And検索できる

SELECT * FROM favorites WHERE user_id = 1 AND post_id = 1 LIMIT 1;

:point_down:

App\Favorite::where([
    'user_id' => 1,
    'post_id' => 1,
])->first();

Or検索

And検索は ->where()->where() のようにメソッドチェーンでも書ける
また、メソッドチェーンは Or検索も表せる

SELECT * FROM posts WHERE title LIKE '%Lorem' OR title LIKE '%ipsum%';

:point_down:

App\Post::where('title', 'LIKE', '%Lorem')
->orWhere('title', 'LIKE', '%ipsum%')
->get();

複雑な検索

コールバックを使用すれば複雑な条件も表せる

SELECT * FROM posts
 WHERE (title LIKE '%Lorem' OR title LIKE '%ipsum%')
  AND (created_at IS NULL OR updated_at IS NULL);

:point_down:

App\Post::where(function ($query) {
    return $query
    ->where('title', 'LIKE', '%Lorem')
    ->orWhere('title', 'LIKE', '%ipsum%');
})
->where(function ($query) {
    return $query
    ->whereNull('created_at')
    ->orWhereNull('updated_at');
})->get();

モデルの作成

INSERT INTO favorites (user_id, post_id) VALUES (1, 2);
App\Favorite::create([
    'user_id' => 1,
    'post_id' => 2,
]);

モデルの更新

UPDATE posts SET updated_at = NOW();

:point_down:

App\Post::query()->update([
    'updated_at' => \Carbon\Carbon::now(),
]);

モデルの(物理)削除

DELETE FROM favorites WHERE user_id = 1 AND post_id = 1;
App\Favorite::where([
    'user_id' => 1,
    'post_id' => 1,
])->delete();

参考ページ
https://readouble.com/laravel/6.x/ja/eloquent.html
https://stackoverflow.com/questions/19325312/how-to-create-multiple-where-clause-query-using-laravel-eloquent
https://stackoverflow.com/questions/15622710/how-to-set-every-row-to-the-same-value-with-laravels-eloquent-fluent

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

そろそろaws初めてみよか#3~RDSとの接続~

はじめに

前回CodeStarのIDE環境(Cloud9)からコード編集Deployまではうまく行きました。
今度はいよいよ失敗していた(=環境が整っていなかった)DB接続を試します。

RDSの作成

RDSのコンソール画面の[データベースの作成]から作成します。
01.png

今回はMariaDBにしてみました。
02-1.png
もちろん無料枠でDBインスタンス名、マスターユーザ名、マスターパスワードを入力します。
解説には@も逝けると書いてありますが、パスワードを確認欄のVaridationで弾かれるので@は無理っす
02-2.png
ここはデフォルトのまま
02-3.png
接続をDefault VPCとしました。
02-4.png
で最後に[データベースの作成]を押せば5~10分位で出来上がります。
02-5.png

RDSとの接続設定

このままではDefault VPCにCodeStarで作成したphp-laravelインスタンスとRDBインスタンスの疎通が取れません。
なぜならDefault VPCにMariaDBポートに対する接続設定が入っていないからです。これを設定していきます。

必要な情報は
- 接続元サーバとなるインスタンスのプライベートIP
- 接続先サーバで利用するポート番号

まずはCodeStarで作成したphp-laravelインスタンスのプライベートIPを確認します。
EC2ダッシュボードに移動し、インスタンスを表示します。
そうするとCodeStarのプロジェクト名-WebAppというインスタンスがいますのでそのプライベートIPをコピーしNodepadなどに書き写しておきます。
01.png

ポート番号はMariaDB標準から変えていないので3306ですね。(RDSの作成時に替えた場合はその値に)

RDSがぶら下がっているVPCからアクセスしましょうか。
Amazon RDSのダッシュボードに移り、データベースメニューからDB識別子のリンクをクリックします。
02.png
03.png
ここに出てくるVPC-セキュリティグループのリンクをクリックします。
04.png
EC2ダッシュボードのネットワーク&セキュリティ>セキュリティーグループにフィルターがかかった状態で遷移します。
画面下部のインバウンドをクリックし、先ほどのプライベートIPとポート番号を指定します。
05.png

RDSとの接続確認

では、CodeStarのプロジェクトのインスタンスにTeraTermで接続します。
初期状態ではmysqlのモジュールも入っていないのでインストールします。
※PHP実行サーバーに入れたくない!ってセキュリティ意識の高い方は別の運用用EC2を立ち上げ操作を行ってください。
 その際は、上のRDSとの接続で指定したインバウンドの他に運用用EC2のプライベートIPも定義してあげます。

コマンドが入っていないことの確認(笑)
-hで指定するホスト名はRDSダッシュボードのデータベース識別子を選択した後の画面にでるエンドポイントのホスト名です。

[ec2-user@ip-172-31-29-127 phplaravel]$ mysql -u admin -p -h laravel-db.culgyynq9ap1.us-east-2.rds.amazonaws.com
-bash: mysql: command not found
[ec2-user@ip-172-31-29-127 phplaravel]$ sudo yum install -y mysql
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main                                                | 2.1 kB     00:00
amzn-updates                                             | 2.5 kB     00:00
Resolving Dependencies
--> Running transaction check
---> Package mysql.noarch 0:5.5-1.6.amzn1 will be installed
--> Processing Dependency: mysql55 >= 5.5 for package: mysql-5.5-1.6.amzn1.noarch
--> Running transaction check
---> Package mysql55.x86_64 0:5.5.62-1.23.amzn1 will be installed
--> Processing Dependency: real-mysql55-libs(x86-64) = 5.5.62-1.23.amzn1 for package: mysql55-5.5.62-1.23.amzn1.x86_64
--> Processing Dependency: mysql-config for package: mysql55-5.5.62-1.23.amzn1.x86_64
--> Running transaction check
---> Package mysql-config.x86_64 0:5.5.62-1.23.amzn1 will be installed
---> Package mysql55-libs.x86_64 0:5.5.62-1.23.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package           Arch        Version                  Repository         Size
================================================================================
Installing:
 mysql             noarch      5.5-1.6.amzn1            amzn-main         2.7 k
Installing for dependencies:
 mysql-config      x86_64      5.5.62-1.23.amzn1        amzn-updates       49 k
 mysql55           x86_64      5.5.62-1.23.amzn1        amzn-updates      7.5 M
 mysql55-libs      x86_64      5.5.62-1.23.amzn1        amzn-updates      816 k

Transaction Summary
================================================================================
Install  1 Package (+3 Dependent packages)

Total download size: 8.3 M
Installed size: 31 M
Downloading packages:
(1/4): mysql-5.5-1.6.amzn1.noarch.rpm                      | 2.7 kB   00:00
(2/4): mysql-config-5.5.62-1.23.amzn1.x86_64.rpm           |  49 kB   00:00
(3/4): mysql55-libs-5.5.62-1.23.amzn1.x86_64.rpm           | 816 kB   00:00
(4/4): mysql55-5.5.62-1.23.amzn1.x86_64.rpm                | 7.5 MB   00:00
--------------------------------------------------------------------------------
Total                                              9.9 MB/s | 8.3 MB  00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : mysql55-libs-5.5.62-1.23.amzn1.x86_64                        1/4
  Installing : mysql-config-5.5.62-1.23.amzn1.x86_64                        2/4
  Installing : mysql55-5.5.62-1.23.amzn1.x86_64                             3/4
  Installing : mysql-5.5-1.6.amzn1.noarch                                   4/4
  Verifying  : mysql-5.5-1.6.amzn1.noarch                                   1/4
  Verifying  : mysql-config-5.5.62-1.23.amzn1.x86_64                        2/4
  Verifying  : mysql55-libs-5.5.62-1.23.amzn1.x86_64                        3/4
  Verifying  : mysql55-5.5.62-1.23.amzn1.x86_64                             4/4

Installed:
  mysql.noarch 0:5.5-1.6.amzn1

Dependency Installed:
  mysql-config.x86_64 0:5.5.62-1.23.amzn1   mysql55.x86_64 0:5.5.62-1.23.amzn1
  mysql55-libs.x86_64 0:5.5.62-1.23.amzn1

Complete!
[ec2-user@ip-172-31-29-127 phplaravel]$ 

気を取り直してもう一度。今度はちゃんと接続できました。

[ec2-user@ip-172-31-29-127 phplaravel]$ mysql -u admin -p -h laravel-db.culgyynq9ap1.us-east-2.rds.amazonaws.com
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 234
Server version: 5.5.5-10.2.21-MariaDB-log Source distribution

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

これでCodeStarのインスタンスからRDSへの接続が可能となりました。

RDSにデータベースを作成する

ここはMariaDBのコマンドなので覚書です。

mysql> CREATE DATABASE laravel DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| innodb             |
| laravel            |
| mysql              |
| performance_schema |
+--------------------+
5 rows in set (0.00 sec)

mysql> \q
Bye

これでlaravel用のDBのガワができました。
本当はマスターユーザではなくLaravel用データベース接続ユーザを作るべきでしょうが
そこはスルーしました。

いよいよphp artisan migrate

ここまで来たらいよいよlaravelからDBをmigrateしてやります。
デフォルトの接続設定がローカルホストでしたのでまずは.envを書き換えます。

[ec2-user@ip-172-31-29-127 ~]$ cd /var/www/phplaravel/
[ec2-user@ip-172-31-29-127 phplaravel]$ cat .env
APP_ENV=local
APP_KEY=base64:CHANGEMECHANGEMECHANGEMECHANGEMECHANGEMECHA=
APP_DEBUG=false
APP_LOG_LEVEL=error
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

PUSHER_APP_ID=
PUSHER_KEY=
PUSHER_SECRET=
[ec2-user@ip-172-31-29-127 phplaravel]$

これを書き換えます。具体的には以下の様にします。

Env Value
DB_CONNECTION mysql
DB_HOST laravel-db.culgyynq9ap1.us-east-2.rds.amazonaws.com
DB_PORT 3306
DB_DATABASE laravel
DB_USERNAME admin
DB_PASSWORD ***********
[ec2-user@ip-172-31-29-127 phplaravel]$ vi .env
[ec2-user@ip-172-31-29-127 phplaravel]$ cat .env
APP_ENV=local
APP_KEY=base64:CHANGEMECHANGEMECHANGEMECHANGEMECHANGEMECHA=
APP_DEBUG=false
APP_LOG_LEVEL=error
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=laravel-db.culgyynq9ap1.us-east-2.rds.amazonaws.com
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=admin
DB_PASSWORD=***********

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

PUSHER_APP_ID=
PUSHER_KEY=
PUSHER_SECRET=
[ec2-user@ip-172-31-29-127 phplaravel]$

ではお待ちかねのartisan migrate

[ec2-user@ip-172-31-29-127 phplaravel]$ php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
[ec2-user@ip-172-31-29-127 phplaravel]$

はい。これでWeb+DBの環境は整いました!

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

ComposerでPlease provide a valid cache pathとなったときの対応スクリプト

https://qiita.com/ponsuke0531/items/f0b68546068ac8922665 を一発でできるスクリプトを書いた。

$ /var/www/laravel# find config/ -type f | xargs grep storage_path \
| grep framework | sed -e 's/^.*storage_path//' \
| tr -d ",\(\)'" | awk '{ print "storage/"$0 }' | xargs mkdir -p
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravelでパスが合っているのに画像が表示されない(404)

当方、Mac環境からwindows環境に移行した際にMacでは表示されていた画像がwindowsでは一切表示されなくなりました。
もちろんフォルダのバックアップを取っていたし、コードもそのままを使用です。

おかしいなと思いつつも色々なパスを書いたが画像は表示されず・・・

blade.php
<img class="logo" src="storage/profile_images/{{$post->id}}.jpg" alt="logo">
<img class="logo" src="../storage/profile_images/{{$post->id}}.jpg" alt="logo">
<img class="logo" src="../../storage/profile_images/{{$post->id}}.jpg" alt="logo">

ページで確認しても、もちろん404エラーです。
画像.png

結論

シンボリックリンク行いましたか?

publicディスクは一般公開へのアクセスを許すファイルを意味しています。デフォルトのpublicディスクは、localドライバを使用しており、storage/app/public下に存在しているファイルです。Webからのアクセスを許すには、public/storageからstorage/app/publicへシンボリックリンクを張る必要があります。
Laravel 5.5 ファイルストレージから引用(https://readouble.com/laravel/5.5/ja/filesystem.html)

シンボリックリンクをやってみよう!

シンボリックリンクは超簡単です。
下記コードをターミナルにて打ち込むだけ

php artisan storage:link
blade.php
<img class="logo" src="../storage/profile_images/4.jpg" alt="logo">

これで画像が表示されました。

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

Use of undefined constant 〇〇 - assumed '〇〇' (this will throw an Error in a future version of PHP)のエラー

問題

Use of undefined constant 〇〇 - assumed '〇〇' (this will throw an Error in a future version of PHP)

というエラーに遭遇した。

解決法

英語で書いてあるとおり
上記の〇〇の部分を '' や ”” で囲っていないことが原因なので確認をする

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

ルーティングは設定しているのにLaravelで404NotFound

1.現象

ルーティングの記述はlaravelの/routes/web.phpに確かに存在しているのに
404 Not Found nginx/1.17.8になってしまう。

スクリーンショット 2020-02-09 16.51.39.png

ルーティングはこちら

routes/web.php
Route::get('/index', 'HelloController@index');

php artisan route:list
でみてもあるんだよなあ

スクリーンショット 2020-02-09 16.57.25.png

2.バージョン

PHP7.2
laravel5.8
docker使用

3.解決方法

どうやらdefault.confのnginxの設定がうまく行ってなさそう

default.conf
server {
  listen 80;
    index index.php index.html;
    root /var/www/public;

  location / {
    root /var/www/public;
    index  index.html index.php;
    }

  location ~ \.php$ {

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

試したところ、以下ではルートディレクトリ"/"しか表示できなかった。
この以下のlocation部分を変更してみる

  location / {
    root /var/www/public;
    index  index.html index.php;
    }

以下のように変更してファイルやディレクトリを探して、なければ、
/index.php$query_stringで内部リダイレクトさせてみる

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

こうしました。

default.conf
server {
  listen 80;
    index index.php index.html;
    root /var/www/public;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

変更後再度、docker-compose up -dを実行
表示できました〜

4.参考

他の方が詳しい記事を書いていました。
https://qiita.com/k_hoso/items/33ccb5e02e73a244ed31
https://teratail.com/questions/182086

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

ルーティングはあるのにLaravelで404NotFound

1.現象

ルーティングの記述はlaravelの/routes/web.phpに確かに存在しているのに
404 Not Found nginx/1.17.8になってしまう。

スクリーンショット 2020-02-09 16.51.39.png

ルーティングはこちら

routes/web.php
Route::get('/index', 'HelloController@index');

php artisan route:list
でみてもあるんだよなあ

スクリーンショット 2020-02-09 16.57.25.png

2.バージョン

PHP7.2
laravel5.8
docker使用

3.解決方法

どうやらdefault.confのnginxの設定がうまく行ってなさそう

default.conf
server {
  listen 80;
    index index.php index.html;
    root /var/www/public;

  location / {
    root /var/www/public;
    index  index.html index.php;
    }

  location ~ \.php$ {

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

試したところ、以下ではルートディレクトリ"/"しか表示できなかった。
この以下のlocation部分を変更してみる

  location / {
    root /var/www/public;
    index  index.html index.php;
    }

以下のように変更してファイルやディレクトリを探して、なければ、
/index.php$query_stringで内部リダイレクトさせてみる

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

こうしました。

default.conf
server {
  listen 80;
    index index.php index.html;
    root /var/www/public;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

変更後再度、docker-compose up -dを実行
表示できました〜

4.参考

他の方が詳しい記事を書いていました。
https://qiita.com/k_hoso/items/33ccb5e02e73a244ed31
https://teratail.com/questions/182086

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

Laravel の make:model をいい感じに使いたい

こんにちはみなさん

Laravelは割と自由に書かせてくれるので、今作っている分を実装するには楽なんですが、全体として実装が微妙にブレることがあるので、後々変な不整合が出そうで怖くなります。
CakePHPはそのあたりをルールによって縛っていて、よりコード量が少なくなるほど彼らの提供する正しい実装になるようになっています。
まあ、何が言いたいかって言うと、自分の実装をあまり信用していないので、ある程度自動生成してもらえれば、やりやすいんじゃないかなぁって思った次第。

そんなわけで、Laravelで大事なコマンドである make:model に注目していきます。

三行で

  • Laravel artisan コマンドの make:model でモデルを自動生成
  • make:model のオプションで必要なファイルのガワを作れる
  • モデルの名前空間を変えたい場合はコマンド自作して上書き

make:model の基本

make:modelEloquentモデルの自動生成コマンドです。

php artisan make:model Post

これを実行すると、app直下に以下のファイルが生成されます。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

app直下に入れたくない場合は名前空間含めて名前を付ける必要があります。

php artisan make:model Entities/Post

これで、app/Entities配下にPost.phpが生成されます。名前空間も合わせて作られています。

make:model のオプションで付随したファイルを自動生成

モデルというのは、プロダクトの中心にあるものですので、こいつをもとにしていろんな処理を作っていくことになると思っています。モデルを作ったら、そいつを取得するためのコントローラやデータベースの作成、テスト用のファクトリーとかを作っていくことになるわけですが、そういうのはモデルと一緒に作ってしまえばいいのではと考えるわけです。

どんなオプションがあるかは -h オプションで見れます。

php artisan make:model -h
Description:
  Create a new Eloquent model class

Usage:
  make:model [options] [--] <name>

Arguments:
  name                  The name of the class

Options:
  -a, --all             Generate a migration, factory, and resource controller for the model
  -c, --controller      Create a new controller for the model
  -f, --factory         Create a new factory for the model
      --force           Create the class even if the model already exists
  -m, --migration       Create a new migration file for the model
  -p, --pivot           Indicates if the generated model should be a custom intermediate table model
  -r, --resource        Indicates if the generated controller should be a resource controller
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
      --env[=ENV]       The environment the command should run under
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

まあ、all使えばいいのでは、ってことです。

-m: マイグレーションを一緒に作る

EloquentモデルはORMなので、たいていなにかのテーブルとひも付きます。また、Eloquentモデルは、テーブル名の指定がない場合は自身の名前の複数形のテーブルを参照するのですが、そのあたりを考えたくない場合は、その規約にあった名前のテーブルのマイグレーションを予め作っておくのが吉です。

というわけで、マイグレーションを一緒に作ります。

# php artisan make:model Post -m
Model created successfully.
Created Migration: 2020_01_19_073425_create_posts_table

すると、以下のようなファイルができています。

databases/migrations/2020_01_19_073425_create_posts_table.php
<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

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

本当はDjangoみたいにモデルの方でデータ型を指定したいところですが。。。こっちのほうがいい部分もあるので、一概にどっちがいいとは言えませんな。

-f: ファクトリーを一緒に作る

モデルを作ったら、そいつのファクトリーを一緒に作っておくのがマナーってやつですよね(????)。
それならいっそ、モデルと一緒に作っちゃえばいいでしょう。

# php artisan make:model Post -f
Model created successfully.
Factory created successfully.

これで次のファイルができています。

paratest/database/factories/PostFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Post;
use Faker\Generator as Faker;

$factory->define(Post::class, function (Faker $faker) {
    return [
        //
    ];
});

まあ、ただの空箱ですが。

-c: コントローラを一緒に作る

Webアプリは、極論、Webのリソースに対する操作になりますので、中心となるモデルをどんなふうにいじるかを決定するコントローラを一緒に作る場合があります。
それなら、やっぱり一緒に作っちゃうのが良いのではってことになります。

# php artisan make:model Post -c
Model created successfully.
Controller created successfully.

これででいるわけですが。。。

paratest/app/Http/Controllers/PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
    //
}

もう少し、こう、scaffolding じみた感じに色々作ってくれていいのだが。。。

-r: リソースコントローラも一緒に作る

-cオプションだと、ただの空箱コントローラが作られましたが、-rオプションを付ければリソースコントローラを作ることができます。

fully.
root@334281a14de2:/var/www# php artisan make:model Post -r
Model created successfully.
Controller created successfully.

コンソールの結果は何も変わりませんが、出力結果が変わります。

paratest/app/Http/Controllers/PostController.php
<?php

namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        //
    }
}

ここまで作ってくれるのなら、デフォルトのコードも作ってくれればいいのに。。。
もちろん、これを作っただけでは動かないので、あとでrouterに登録するのを忘れないようにしましょう。
Route::resource('post', 'PostController');で行けるはずです。

-a: -m, -f, -r 全部入り

ここまでやってきたやつを全部入れるのなら、-aオプションが便利です。

# php artisan make:model Post -a
Model created successfully.
Factory created successfully.
Created Migration: 2020_01_19_081214_create_posts_table
Controller created successfully.

モデル名さえ決めていれば、残りのファイルは一括自動生成!
これが楽だと思います。

もちろん、プロダクトが成長していき、単純な構造ではすまなくなってしまえば、このようにコントローラまで一緒に全部作るというのは厳しいこともあるかもですが、仮説検証のようなとりあえず試してみたいというときであればこれで良いのではと思います。

初期の名前空間を変える

make:modelはモデル名を指定すると、そのままapp直下にクラスファイルが生成されるわけですが、これがLaravelの教えだとしても、個人的にはモデルにそれなりの名前空間をつけておきたいところ。
例えば、モデルは必ずApp\Entitiesに入れるというのであれば、毎回モデルを作るごとにEntities\ModelNameって入力するのは面倒です。

なので、こんなコードをapp/Console/Commands配下に入れます。

MyMakeModel.php
<?php

namespace App\Console\Commands;

use Illuminate\Foundation\Console\ModelMakeCommand;

class MyMakeModel extends ModelMakeCommand
{
    protected function getDefaultNamespace($rootNamespace)
    {
        return $rootNamespace.'\Entities';
    }
}

あとは、普通にphp artisan make:model ModelNameというコマンドを叩くだけで、先に設定した名前空間付きのモデルが作られます。
なお、-r-fなどで、リソースコントローラやファクトリを一緒に作った場合は、モデルの名前空間もちゃんと踏襲してくれていますので、おすすめです。

まとめ

というわけで、Laravelにおけるモデルの自動生成のちょっとした使い方を見てみました。自分でやってて、割と発見があったかなぁという印象です。
機械的に作れるところはとっとと自動生成しちゃって、肝心のモデルの設計を頑張ろうってところでしょうか。

今回はこんなところです。

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

vagrant reload --provisionができなくて、homesteadさんをdestoryした日のこと

きっかっけはphp artisan migrate

そもそもphp artisan migrateができなっかった時

Illuminate\Database\QueryException  : SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: NO) (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

のエラーが出て、↓

$ mysql -u root -p

しても

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

だった故に、、、

えーいこれやっとけばなんとかなるさ〜

$ vagrant reload --provision

からの〜

homestead: ERROR
    homestead:  1045 (28000)
    homestead: : Access denied for user 'homestead'@'localhost' (using password: YES)
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.

え?昨日まであんなに一緒だったのに、、、、

using password: YES

夕暮れはもう違う顔。。。(意訳:PW設定した記憶ございません)

gdgdと悩んでみるも

MBP-3:Homestead xxx$ mysql_safe --skip-grant-tables &
[1] 9032
MBP-3:Homestead xxx$ -bash: mysql_safe: command not found
mysql_safe --skip-grant-t
$ kill -KILL [mysqld_safe [1] 6582]
$ kill -KILL [mysqld 2020-02-08T01:07:59.960528Z mysqld_safe Logging to '/var/log/mysql/error.log'.]

こんなの試したり、TARITARI
(余計に手がつけられなくなった??)

メンターさんに聞いてもPWの隠し場所が分からず。。。
ここで僕たちは非常な選択を選ばざるをえなかった。

destory(ステラ--!!)

MBP-3:Homestead xxxx$ vagrant destroy
    homestead: Are you sure you want to destroy the 'homestead' VM? [y/N] y
==> homestead: Destroying VM and associated drives..

さよならバイバイ!

蘇るさ何度でも

復活の呪文を

$ vagrant up

gokuri

Bringing machine 'homestead' up with 'virtualbox' provider...
==> homestead: Importing base box 'laravel/homestead'...
==> homestead: Matching MAC address for NAT networking...
==> homestead: Checking if box 'laravel/homestead' version '9.2.0' is up to date...
==> homestead: Setting the name of the VM: homestead
==> homestead: Fixed port collision for 3306 => 33060. Now on port 2200.
==> homestead: Clearing any previously set network interfaces...
==> homestead: Preparing network interfaces based on configuration...

キターー!!

てことで、

vagrant@homestead:~/code/laravel$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2020_02_05_205342_create_tasks_table
Migrated:  2020_02_05_205342_create_tasks_table

無事完了!

↓マイグレとは?
https://laraweb.net/knowledge/714/

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

laravelで都道府県プルダウンメニューを表示させる手順

laravelで都道府県のプルダウンメニューを導入したのでその手順をメモします

都道府県名一覧表をつくる

configディレクトリ下に下記ファイルを作成。

pref.php
<?php 
return array(
  '0' => '未選択',
  '1' => '北海道', 
  '2' => '青森県', 
  '3' => '岩手県', 
  '4' => '宮城県',
  '5' => '秋田県', 
  '6' => '山形県', 
  '7' => '福島県', 
  '8' => '茨城県',
  '9' => '栃木県', 
  '10' => '群馬県', 
  '11' => '埼玉県', 
  '12' => '千葉県',
  '13' => '東京都', 
  '14' => '神奈川県', 
  '15' => '新潟県', 
  '16' => '富山県',
  '17' => '石川県', 
  '18' => '福井県', 
  '19' => '山梨県', 
  '20' => '長野県', 
  '21' => '岐阜県', 
  '22' => '静岡県', 
  '23' => '愛知県', 
  '24' => '三重県',
  '25' => '滋賀県', 
  '26' => '京都府', 
  '27' => '大阪府', 
  '28' => '兵庫県',
  '29' => '奈良県', 
  '30' => '和歌山県', 
  '31' => '鳥取県', 
  '32' => '島根県',
  '33' => '岡山県', 
  '34' => '広島県', 
  '35' => '山口県', 
  '36' => '徳島県',
  '37' => '香川県',
  '38' => '愛媛県',
  '39' => '高知県', 
  '40' => '福岡県',
  '41' => '佐賀県', 
  '42' => '長崎県', 
  '43' => '熊本県', 
  '44' => '大分県',
  '45' => '宮崎県', 
  '46' => '鹿児島県', 
  '47' => '沖縄県'
);
?>

Viewに下記を追記

create.blade.php
<select type="text" class="form-control" name="area">                          
    @foreach(config('pref') as $key => $score)
        <option value="{{ $score }}">{{ $score }}</option>
    @endforeach
</select>

select、optionタグについて

  • selectタグでプルダウンなどのセレクトボックスを作成できます。
  • optionタグはselectタグとセットて使われ、セレクトボックス内の選択肢について指定します。value属性にプルダウンの項目を記載します。
  • selectタグのtype属性に1行の入力フィールドである'text'を選択。name属性にはこの入力欄の名前を決めて入力します。入力した値(都道府県)をデータベースから取り出すときにこの名前を参照しますので必須項目です。

foreachについて

  • foreach分は今回のような連想配列の場合は下記のような構成になります。
foreach ($array as $key => $value)
  • configディレクトリ下のpref.phpファイルに記載した配列を呼び出したいときはconfig('pref')となります。
$key => $value

は下記に対応します。

'1' => '北海道'
  • valueの値を$keyに設定すると、都道府県名ではなく数字がデータベースに保存されてしまい、この後データを取得する際に数字が表示されてしまうので注意です。

参照

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

そろそろaws初めてみよか#2~CodeStarによるコード修正からDeployまで~

はじめに

そろそろaws初めてみよか~まずは触ってみた~で紹介したようにawsの海をもがいている訳ですが(笑)

CodeStarの環境が整ったので試しにコードを編集しCommitしてDeployまで流れるか確認
その後、DBのmigrateをしてみようと思います。
結果からお伝えすると、
- コードCommitからDeployまではOK
- DBのmigrateはNG
でした。

コード編集からDeployまで

Cloud9(IDE)を利用してコードを修正、それをGit CommitしてDeployまでの流れを確認しました。

CodeStarからプロジェクトを選択し、Cloud9を起動します。
暫くするとGitからPullしてきますので確認します。

今回は簡単にWelcomePageのタイトルを修正します。
修正と言っても「!!」を後ろにつけただけという(笑)

01.png

AWSのGitにCommitします。

ec2-user:~/environment $ cd php-laravel/
ec2-user:~/environment/php-laravel (master) $ git add .
ec2-user:~/environment/php-laravel (master) $ git commit -m 'change Title'
[master 42bc467] change Title
 Committer: EC2 Default User <ec2-user@ip-172-31-20-112.us-east-2.compute.internal>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 1 file changed, 1 insertion(+), 1 deletion(-)
ec2-user:~/environment/php-laravel (master) $ git push origin master
Counting objects: 5, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 435 bytes | 435.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0)
To https://git-codecommit.us-east-2.amazonaws.com/v1/repos/php-laravel
   a0c0157..42bc467  master -> master
ec2-user:~/environment/php-laravel (master) $ 

すると勝手にDeployまで走っている様子がパイプラインの画面から確認できます。

02.png

実際のアプリケーションを確認するにはCodeStarダッシュボードの「アプリケーションのエンドポイント」をクリック

03.png

見辛いですが、タイトルが変わってます(笑)

04.png

こんな感じで開発していくのは分かるのですが…
本番環境とローカル環境のずれを前回確認しているのでどうやって実際に使っていくのかは
まだイメージできていません(^^;

DBとの接続

環境の確認

CodeStarによりプロジェクトを作成すると実行するインスタンスとCloud9(IDE)用のインスタンスが生成されます。
興味があるのは実行するインスタンス側なのでEC2ダッシュボード画面からインスタンス「php-laravel-WebApp」の「パブリック DNS (IPv4)」にTeraTermで接続します。
※ちなみに前回の記事ではプロジェクト名を「laravel」としてましたが、何度か削除に失敗して「php-laravel」としています。
 関連するリソースが綺麗に消えてくれなくて困っています(笑)


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-29-127 ~]$ cd /var/www/phplaravel/
[ec2-user@ip-172-31-29-127 phplaravel]$ ls
app        composer.json  database     package.json  resources   storage
artisan    composer.lock  gulpfile.js  phpunit.xml   routes      tests
bootstrap  config         index.php    public        server.php  vendor
[ec2-user@ip-172-31-29-127 phplaravel]$ php artisan migrate


  [Illuminate\Database\QueryException]
  could not find driver (SQL: select * from information_schema.tables where t
  able_schema = homestead and table_name = migrations)



  [PDOException]
  could not find driver

えっと...could not find driverって


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-29-127 ~]$ cd /var/www/phplaravel/
[ec2-user@ip-172-31-29-127 phplaravel]$ ls -alF
total 220
drwxr-xr-x 12 ec2-user ec2-user   4096 Feb  9 00:01 ./
drwxr-xr-x  8 root     root       4096 Feb  8 19:11 ../
drwxr-xr-x  6 ec2-user ec2-user   4096 Feb  9 00:01 app/
-rw-r--r--  1 ec2-user ec2-user   1646 Feb  9 00:01 artisan
drwxr-xr-x  3 ec2-user ec2-user   4096 Feb  9 00:01 bootstrap/
-rw-r--r--  1 ec2-user ec2-user   1283 Feb  9 00:01 composer.json
-rw-r--r--  1 ec2-user ec2-user 130327 Feb  9 00:00 composer.lock
drwxr-xr-x  2 ec2-user ec2-user   4096 Feb  9 00:01 config/
drwxr-xr-x  5 ec2-user ec2-user   4096 Feb  9 00:01 database/
-rw-r--r--  1 ec2-user ec2-user    543 Feb  9 00:01 .env
-rw-r--r--  1 ec2-user ec2-user    543 Feb  9 00:00 .env.example
-rw-r--r--  1 ec2-user ec2-user     61 Feb  9 00:01 .gitattributes
-rw-r--r--  1 ec2-user ec2-user     80 Feb  9 00:01 .gitignore
-rw-r--r--  1 ec2-user ec2-user    558 Feb  9 00:01 gulpfile.js
-rw-r--r--  1 ec2-user ec2-user   1776 Feb  9 00:01 index.php
-rw-r--r--  1 ec2-user ec2-user    390 Feb  9 00:00 package.json
-rw-r--r--  1 ec2-user ec2-user    930 Feb  9 00:01 phpunit.xml
drwxr-xr-x  5 ec2-user ec2-user   4096 Feb  9 00:01 public/
drwxr-xr-x  5 ec2-user ec2-user   4096 Feb  9 00:01 resources/
drwxr-xr-x  2 ec2-user ec2-user   4096 Feb  9 00:01 routes/
-rw-r--r--  1 ec2-user ec2-user    563 Feb  9 00:01 server.php
drwxrwxr-x  5 ec2-user apache     4096 Feb  9 00:01 storage/
drwxr-xr-x  2 ec2-user ec2-user   4096 Feb  9 00:01 tests/
drwxr-xr-x 32 ec2-user ec2-user   4096 Feb  9 00:01 vendor/
[ec2-user@ip-172-31-29-127 phplaravel]$ more .env
APP_ENV=local
APP_KEY=base64:CHANGEMECHANGEMECHANGEMECHANGEMECHANGEMECHA=
APP_DEBUG=false
APP_LOG_LEVEL=error
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

PUSHER_APP_ID=
PUSHER_KEY=
PUSHER_SECRET=
[ec2-user@ip-172-31-29-127 phplaravel]$

「.env」を覗くとローカルホストの「mysql」って書いてあります(汗
でもmysql入ってないし…


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-29-127 ~]$ rpm -qa | grep mysql
[ec2-user@ip-172-31-29-127 ~]$ 

そんな訳で追加インストール

無いのならインストールするしかないのでまずはPDOのmysqlをインストールしました。
$ sudo yum install -y php73-mysqlnd

するとPDOの例外が変わりましたね。
[PDOException]
SQLSTATE[HY000] [2002] Connection refused

DB_DATABASE、DB_USERNAME、DB_PASSWORDが違うので、これで正解です(笑)

[ec2-user@ip-172-31-29-127 phplaravel]$ sudo yum list *mysql*
Loaded plugins: priorities, update-motd, upgrade-helper
Available Packages
MySQL-python26.x86_64                          1.2.3-11.14.amzn1    amzn-main
MySQL-python27.x86_64                          1.2.3-11.14.amzn1    amzn-main
apr-util-mysql.x86_64                          1.5.4-6.18.amzn1     amzn-main
collectd-mysql.x86_64                          5.8.0-2.19.amzn1     amzn-main
dovecot-mysql.x86_64                           1:2.2.10-5.17.amzn1  amzn-main
exim-mysql.x86_64                              4.92-1.25.amzn1      amzn-updates
freeradius-mysql.x86_64                        2.2.6-7.16.amzn1     amzn-main
libdbi-dbd-mysql.x86_64                        0.8.3-5.1.5.amzn1    amzn-main
lighttpd-mod_authn_mysql.x86_64                1.4.53-1.36.amzn1    amzn-updates
lighttpd-mod_mysql_vhost.x86_64                1.4.53-1.36.amzn1    amzn-updates
mod_auth_mysql.x86_64                          1:3.0.0-18.10.amzn1  amzn-main
mysql.noarch                                   5.5-1.6.amzn1        amzn-main
mysql-bench.noarch                             5.5-1.6.amzn1        amzn-main
mysql-common.noarch                            5.5-1.6.amzn1        amzn-main
mysql-config.x86_64                            5.5.62-1.23.amzn1    amzn-updates
mysql-connector-java.noarch                    1:5.1.12-2.10.amzn1  amzn-main
mysql-connector-odbc.x86_64                    5.1.11-1.12.amzn1    amzn-main
mysql-devel.noarch                             5.5-1.6.amzn1        amzn-main
mysql-embedded.noarch                          5.5-1.6.amzn1        amzn-main
mysql-embedded-devel.noarch                    5.5-1.6.amzn1        amzn-main
mysql-libs.noarch                              5.5-1.6.amzn1        amzn-main
mysql-server.noarch                            5.5-1.6.amzn1        amzn-main
mysql-test.noarch                              5.5-1.6.amzn1        amzn-main
mysql51.x86_64                                 5.1.73-8.72.amzn1    amzn-main
mysql51-bench.x86_64                           5.1.73-8.72.amzn1    amzn-main
mysql51-common.x86_64                          5.1.73-8.72.amzn1    amzn-main
mysql51-devel.x86_64                           5.1.73-8.72.amzn1    amzn-main
mysql51-embedded.x86_64                        5.1.73-8.72.amzn1    amzn-main
mysql51-embedded-devel.x86_64                  5.1.73-8.72.amzn1    amzn-main
mysql51-libs.i686                              5.1.73-8.72.amzn1    amzn-main
mysql51-libs.x86_64                            5.1.73-8.72.amzn1    amzn-main
mysql51-server.x86_64                          5.1.73-8.72.amzn1    amzn-main
mysql51-test.x86_64                            5.1.73-8.72.amzn1    amzn-main
mysql55.x86_64                                 5.5.62-1.23.amzn1    amzn-updates
mysql55-bench.x86_64                           5.5.62-1.23.amzn1    amzn-updates
mysql55-devel.x86_64                           5.5.62-1.23.amzn1    amzn-updates
mysql55-embedded.x86_64                        5.5.62-1.23.amzn1    amzn-updates
mysql55-embedded-devel.x86_64                  5.5.62-1.23.amzn1    amzn-updates
mysql55-libs.i686                              5.5.62-1.23.amzn1    amzn-updates
mysql55-libs.x86_64                            5.5.62-1.23.amzn1    amzn-updates
mysql55-server.x86_64                          5.5.62-1.23.amzn1    amzn-updates
mysql55-test.x86_64                            5.5.62-1.23.amzn1    amzn-updates
mysql56.x86_64                                 5.6.46-1.35.amzn1    amzn-updates
mysql56-bench.x86_64                           5.6.46-1.35.amzn1    amzn-updates
mysql56-common.i686                            5.6.46-1.35.amzn1    amzn-updates
mysql56-common.x86_64                          5.6.46-1.35.amzn1    amzn-updates
mysql56-devel.x86_64                           5.6.46-1.35.amzn1    amzn-updates
mysql56-embedded.x86_64                        5.6.46-1.35.amzn1    amzn-updates
mysql56-embedded-devel.x86_64                  5.6.46-1.35.amzn1    amzn-updates
mysql56-errmsg.x86_64                          5.6.46-1.35.amzn1    amzn-updates
mysql56-libs.i686                              5.6.46-1.35.amzn1    amzn-updates
mysql56-libs.x86_64                            5.6.46-1.35.amzn1    amzn-updates
mysql56-server.x86_64                          5.6.46-1.35.amzn1    amzn-updates
mysql56-test.x86_64                            5.6.46-1.35.amzn1    amzn-updates
mysql57.x86_64                                 5.7.28-1.14.amzn1    amzn-updates
mysql57-common.i686                            5.7.28-1.14.amzn1    amzn-updates
mysql57-common.x86_64                          5.7.28-1.14.amzn1    amzn-updates
mysql57-devel.x86_64                           5.7.28-1.14.amzn1    amzn-updates
mysql57-embedded.x86_64                        5.7.28-1.14.amzn1    amzn-updates
mysql57-embedded-devel.x86_64                  5.7.28-1.14.amzn1    amzn-updates
mysql57-errmsg.x86_64                          5.7.28-1.14.amzn1    amzn-updates
mysql57-libs.i686                              5.7.28-1.14.amzn1    amzn-updates
mysql57-libs.x86_64                            5.7.28-1.14.amzn1    amzn-updates
mysql57-server.x86_64                          5.7.28-1.14.amzn1    amzn-updates
mysql57-test.x86_64                            5.7.28-1.14.amzn1    amzn-updates
nagios-plugins-mysql.x86_64                    1.4.16-5.8.amzn1     amzn-main
perl-DBD-MySQL.x86_64                          4.023-5.17.amzn1     amzn-main
perl-DBD-MySQL55.x86_64                        4.023-5.23.amzn1     amzn-main
perl-DBD-MySQL56.x86_64                        4.023-5.21.amzn1     amzn-main
perl-DateTime-Format-MySQL.noarch              0.04-18.2.amzn1      amzn-main
perl-Time-Piece-MySQL.noarch                   0.05-20.2.amzn1      amzn-main
php-ZendFramework-Db-Adapter-Mysqli.noarch     1.12.20-1.12.amzn1   amzn-main
php-ZendFramework-Db-Adapter-Pdo-Mysql.noarch  1.12.20-1.12.amzn1   amzn-main
php-mysql.x86_64                               5.3.29-1.8.amzn1     amzn-main
php-mysqlnd.x86_64                             5.3.29-1.8.amzn1     amzn-main
php54-mysql.x86_64                             5.4.45-1.75.amzn1    amzn-main
php54-mysqlnd.x86_64                           5.4.45-1.75.amzn1    amzn-main
php55-mysqlnd.x86_64                           5.5.38-2.119.amzn1   amzn-main
php56-mysqlnd.x86_64                           5.6.40-1.143.amzn1   amzn-updates
php70-mysqlnd.x86_64                           7.0.33-1.32.amzn1    amzn-updates
php71-mysqlnd.x86_64                           7.1.33-1.43.amzn1    amzn-updates
php72-mysqlnd.x86_64                           7.2.26-1.19.amzn1    amzn-updates
php73-mysqlnd.x86_64                           7.3.13-1.22.amzn1    amzn-updates
rsyslog-mysql.x86_64                           5.8.10-9.26.amzn1    amzn-main
ruby-mysql.x86_64                              2.8.2-1.11.amzn1     amzn-main

[ec2-user@ip-172-31-29-127 phplaravel]$ sudo yum install -y php73-mysqlnd
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
--> Running transaction check
---> Package php73-mysqlnd.x86_64 0:7.3.13-1.22.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch        Version                 Repository         Size
================================================================================
Installing:
 php73-mysqlnd      x86_64      7.3.13-1.22.amzn1       amzn-updates      336 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 336 k
Installed size: 812 k
Downloading packages:
php73-mysqlnd-7.3.13-1.22.amzn1.x86_64.rpm                 | 336 kB   00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : php73-mysqlnd-7.3.13-1.22.amzn1.x86_64                       1/1
  Verifying  : php73-mysqlnd-7.3.13-1.22.amzn1.x86_64                       1/1

Installed:
  php73-mysqlnd.x86_64 0:7.3.13-1.22.amzn1

Complete!

[ec2-user@ip-172-31-29-127 phplaravel]$ php artisan migrate


  [Illuminate\Database\QueryException]
  SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_s
  chema.tables where table_schema = homestead and table_name = migrations)



  [PDOException]
  SQLSTATE[HY000] [2002] Connection refused


[ec2-user@ip-172-31-29-127 phplaravel]$

RDS(DBサーバ)と接続する準備は整ったのでまたキャプチャー取り始めます(笑)

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

そろそろaws初めてみよか#2

はじめに

そろそろaws初めてみよかで紹介したようにawsの海をもがいている訳ですが(笑)

CodeStarの環境が整ったので試しにコードを編集しCommitしてDeployまで流れるか確認
その後、DBのmigrateをしてみようと思います。
結果からお伝えすると、
- コードCommitからDeployまではOK
- DBのmigrateはNG
でした。

コード編集からDeployまで

Cloud9(IDE)を利用してコードを修正、それをGit CommitしてDeployまでの流れを確認しました。

CodeStarからプロジェクトを選択し、Cloud9を起動します。
暫くするとGitからPullしてきますので確認します。

今回は簡単にWelcomePageのタイトルを修正します。
修正と言っても「!!」を後ろにつけただけという(笑)

01.png

AWSのGitにCommitします。

ec2-user:~/environment $ cd php-laravel/
ec2-user:~/environment/php-laravel (master) $ git add .
ec2-user:~/environment/php-laravel (master) $ git commit -m 'change Title'
[master 42bc467] change Title
 Committer: EC2 Default User <ec2-user@ip-172-31-20-112.us-east-2.compute.internal>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 1 file changed, 1 insertion(+), 1 deletion(-)
ec2-user:~/environment/php-laravel (master) $ git push origin master
Counting objects: 5, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 435 bytes | 435.00 KiB/s, done.
Total 5 (delta 4), reused 0 (delta 0)
To https://git-codecommit.us-east-2.amazonaws.com/v1/repos/php-laravel
   a0c0157..42bc467  master -> master
ec2-user:~/environment/php-laravel (master) $ 

すると勝手にDeployまで走っている様子がパイプラインの画面から確認できます。

02.png

実際のアプリケーションを確認するにはCodeStarダッシュボードの「アプリケーションのエンドポイント」をクリック

03.png

見辛いですが、タイトルが変わってます(笑)

04.png

こんな感じで開発していくのは分かるのですが…
本番環境とローカル環境のずれを前回確認しているのでどうやって実際に使っていくのかは
まだイメージできていません(^^;

DBとの接続

環境の確認

CodeStarによりプロジェクトを作成すると実行するインスタンスとCloud9(IDE)用のインスタンスが生成されます。
興味があるのは実行するインスタンス側なのでEC2ダッシュボード画面からインスタンス「php-laravel-WebApp」の「パブリック DNS (IPv4)」にTeraTermで接続します。
※ちなみに前回の記事ではプロジェクト名を「laravel」としてましたが、何度か削除に失敗して「php-laravel」としています。
 関連するリソースが綺麗に消えてくれなくて困っています(笑)


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-29-127 ~]$ cd /var/www/phplaravel/
[ec2-user@ip-172-31-29-127 phplaravel]$ ls
app        composer.json  database     package.json  resources   storage
artisan    composer.lock  gulpfile.js  phpunit.xml   routes      tests
bootstrap  config         index.php    public        server.php  vendor
[ec2-user@ip-172-31-29-127 phplaravel]$ php artisan migrate


  [Illuminate\Database\QueryException]
  could not find driver (SQL: select * from information_schema.tables where t
  able_schema = homestead and table_name = migrations)



  [PDOException]
  could not find driver

えっと...could not find driverって


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-29-127 ~]$ cd /var/www/phplaravel/
[ec2-user@ip-172-31-29-127 phplaravel]$ ls -alF
total 220
drwxr-xr-x 12 ec2-user ec2-user   4096 Feb  9 00:01 ./
drwxr-xr-x  8 root     root       4096 Feb  8 19:11 ../
drwxr-xr-x  6 ec2-user ec2-user   4096 Feb  9 00:01 app/
-rw-r--r--  1 ec2-user ec2-user   1646 Feb  9 00:01 artisan
drwxr-xr-x  3 ec2-user ec2-user   4096 Feb  9 00:01 bootstrap/
-rw-r--r--  1 ec2-user ec2-user   1283 Feb  9 00:01 composer.json
-rw-r--r--  1 ec2-user ec2-user 130327 Feb  9 00:00 composer.lock
drwxr-xr-x  2 ec2-user ec2-user   4096 Feb  9 00:01 config/
drwxr-xr-x  5 ec2-user ec2-user   4096 Feb  9 00:01 database/
-rw-r--r--  1 ec2-user ec2-user    543 Feb  9 00:01 .env
-rw-r--r--  1 ec2-user ec2-user    543 Feb  9 00:00 .env.example
-rw-r--r--  1 ec2-user ec2-user     61 Feb  9 00:01 .gitattributes
-rw-r--r--  1 ec2-user ec2-user     80 Feb  9 00:01 .gitignore
-rw-r--r--  1 ec2-user ec2-user    558 Feb  9 00:01 gulpfile.js
-rw-r--r--  1 ec2-user ec2-user   1776 Feb  9 00:01 index.php
-rw-r--r--  1 ec2-user ec2-user    390 Feb  9 00:00 package.json
-rw-r--r--  1 ec2-user ec2-user    930 Feb  9 00:01 phpunit.xml
drwxr-xr-x  5 ec2-user ec2-user   4096 Feb  9 00:01 public/
drwxr-xr-x  5 ec2-user ec2-user   4096 Feb  9 00:01 resources/
drwxr-xr-x  2 ec2-user ec2-user   4096 Feb  9 00:01 routes/
-rw-r--r--  1 ec2-user ec2-user    563 Feb  9 00:01 server.php
drwxrwxr-x  5 ec2-user apache     4096 Feb  9 00:01 storage/
drwxr-xr-x  2 ec2-user ec2-user   4096 Feb  9 00:01 tests/
drwxr-xr-x 32 ec2-user ec2-user   4096 Feb  9 00:01 vendor/
[ec2-user@ip-172-31-29-127 phplaravel]$ more .env
APP_ENV=local
APP_KEY=base64:CHANGEMECHANGEMECHANGEMECHANGEMECHANGEMECHA=
APP_DEBUG=false
APP_LOG_LEVEL=error
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

PUSHER_APP_ID=
PUSHER_KEY=
PUSHER_SECRET=
[ec2-user@ip-172-31-29-127 phplaravel]$

「.env」を覗くとローカルホストの「mysql」って書いてあります(汗
でもmysql入ってないし…


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
[ec2-user@ip-172-31-29-127 ~]$ rpm -qa | grep mysql
[ec2-user@ip-172-31-29-127 ~]$ 

そんな訳で追加インストール

無いのならインストールするしかないのでまずはPDOのmysqlをインストールしました。
$ sudo yum install -y php73-mysqlnd

するとPDOの例外が変わりましたね。
[PDOException]
SQLSTATE[HY000] [2002] Connection refused

DB_DATABASE、DB_USERNAME、DB_PASSWORDが違うので、これで正解です(笑)

[ec2-user@ip-172-31-29-127 phplaravel]$ sudo yum list *mysql*
Loaded plugins: priorities, update-motd, upgrade-helper
Available Packages
MySQL-python26.x86_64                          1.2.3-11.14.amzn1    amzn-main
MySQL-python27.x86_64                          1.2.3-11.14.amzn1    amzn-main
apr-util-mysql.x86_64                          1.5.4-6.18.amzn1     amzn-main
collectd-mysql.x86_64                          5.8.0-2.19.amzn1     amzn-main
dovecot-mysql.x86_64                           1:2.2.10-5.17.amzn1  amzn-main
exim-mysql.x86_64                              4.92-1.25.amzn1      amzn-updates
freeradius-mysql.x86_64                        2.2.6-7.16.amzn1     amzn-main
libdbi-dbd-mysql.x86_64                        0.8.3-5.1.5.amzn1    amzn-main
lighttpd-mod_authn_mysql.x86_64                1.4.53-1.36.amzn1    amzn-updates
lighttpd-mod_mysql_vhost.x86_64                1.4.53-1.36.amzn1    amzn-updates
mod_auth_mysql.x86_64                          1:3.0.0-18.10.amzn1  amzn-main
mysql.noarch                                   5.5-1.6.amzn1        amzn-main
mysql-bench.noarch                             5.5-1.6.amzn1        amzn-main
mysql-common.noarch                            5.5-1.6.amzn1        amzn-main
mysql-config.x86_64                            5.5.62-1.23.amzn1    amzn-updates
mysql-connector-java.noarch                    1:5.1.12-2.10.amzn1  amzn-main
mysql-connector-odbc.x86_64                    5.1.11-1.12.amzn1    amzn-main
mysql-devel.noarch                             5.5-1.6.amzn1        amzn-main
mysql-embedded.noarch                          5.5-1.6.amzn1        amzn-main
mysql-embedded-devel.noarch                    5.5-1.6.amzn1        amzn-main
mysql-libs.noarch                              5.5-1.6.amzn1        amzn-main
mysql-server.noarch                            5.5-1.6.amzn1        amzn-main
mysql-test.noarch                              5.5-1.6.amzn1        amzn-main
mysql51.x86_64                                 5.1.73-8.72.amzn1    amzn-main
mysql51-bench.x86_64                           5.1.73-8.72.amzn1    amzn-main
mysql51-common.x86_64                          5.1.73-8.72.amzn1    amzn-main
mysql51-devel.x86_64                           5.1.73-8.72.amzn1    amzn-main
mysql51-embedded.x86_64                        5.1.73-8.72.amzn1    amzn-main
mysql51-embedded-devel.x86_64                  5.1.73-8.72.amzn1    amzn-main
mysql51-libs.i686                              5.1.73-8.72.amzn1    amzn-main
mysql51-libs.x86_64                            5.1.73-8.72.amzn1    amzn-main
mysql51-server.x86_64                          5.1.73-8.72.amzn1    amzn-main
mysql51-test.x86_64                            5.1.73-8.72.amzn1    amzn-main
mysql55.x86_64                                 5.5.62-1.23.amzn1    amzn-updates
mysql55-bench.x86_64                           5.5.62-1.23.amzn1    amzn-updates
mysql55-devel.x86_64                           5.5.62-1.23.amzn1    amzn-updates
mysql55-embedded.x86_64                        5.5.62-1.23.amzn1    amzn-updates
mysql55-embedded-devel.x86_64                  5.5.62-1.23.amzn1    amzn-updates
mysql55-libs.i686                              5.5.62-1.23.amzn1    amzn-updates
mysql55-libs.x86_64                            5.5.62-1.23.amzn1    amzn-updates
mysql55-server.x86_64                          5.5.62-1.23.amzn1    amzn-updates
mysql55-test.x86_64                            5.5.62-1.23.amzn1    amzn-updates
mysql56.x86_64                                 5.6.46-1.35.amzn1    amzn-updates
mysql56-bench.x86_64                           5.6.46-1.35.amzn1    amzn-updates
mysql56-common.i686                            5.6.46-1.35.amzn1    amzn-updates
mysql56-common.x86_64                          5.6.46-1.35.amzn1    amzn-updates
mysql56-devel.x86_64                           5.6.46-1.35.amzn1    amzn-updates
mysql56-embedded.x86_64                        5.6.46-1.35.amzn1    amzn-updates
mysql56-embedded-devel.x86_64                  5.6.46-1.35.amzn1    amzn-updates
mysql56-errmsg.x86_64                          5.6.46-1.35.amzn1    amzn-updates
mysql56-libs.i686                              5.6.46-1.35.amzn1    amzn-updates
mysql56-libs.x86_64                            5.6.46-1.35.amzn1    amzn-updates
mysql56-server.x86_64                          5.6.46-1.35.amzn1    amzn-updates
mysql56-test.x86_64                            5.6.46-1.35.amzn1    amzn-updates
mysql57.x86_64                                 5.7.28-1.14.amzn1    amzn-updates
mysql57-common.i686                            5.7.28-1.14.amzn1    amzn-updates
mysql57-common.x86_64                          5.7.28-1.14.amzn1    amzn-updates
mysql57-devel.x86_64                           5.7.28-1.14.amzn1    amzn-updates
mysql57-embedded.x86_64                        5.7.28-1.14.amzn1    amzn-updates
mysql57-embedded-devel.x86_64                  5.7.28-1.14.amzn1    amzn-updates
mysql57-errmsg.x86_64                          5.7.28-1.14.amzn1    amzn-updates
mysql57-libs.i686                              5.7.28-1.14.amzn1    amzn-updates
mysql57-libs.x86_64                            5.7.28-1.14.amzn1    amzn-updates
mysql57-server.x86_64                          5.7.28-1.14.amzn1    amzn-updates
mysql57-test.x86_64                            5.7.28-1.14.amzn1    amzn-updates
nagios-plugins-mysql.x86_64                    1.4.16-5.8.amzn1     amzn-main
perl-DBD-MySQL.x86_64                          4.023-5.17.amzn1     amzn-main
perl-DBD-MySQL55.x86_64                        4.023-5.23.amzn1     amzn-main
perl-DBD-MySQL56.x86_64                        4.023-5.21.amzn1     amzn-main
perl-DateTime-Format-MySQL.noarch              0.04-18.2.amzn1      amzn-main
perl-Time-Piece-MySQL.noarch                   0.05-20.2.amzn1      amzn-main
php-ZendFramework-Db-Adapter-Mysqli.noarch     1.12.20-1.12.amzn1   amzn-main
php-ZendFramework-Db-Adapter-Pdo-Mysql.noarch  1.12.20-1.12.amzn1   amzn-main
php-mysql.x86_64                               5.3.29-1.8.amzn1     amzn-main
php-mysqlnd.x86_64                             5.3.29-1.8.amzn1     amzn-main
php54-mysql.x86_64                             5.4.45-1.75.amzn1    amzn-main
php54-mysqlnd.x86_64                           5.4.45-1.75.amzn1    amzn-main
php55-mysqlnd.x86_64                           5.5.38-2.119.amzn1   amzn-main
php56-mysqlnd.x86_64                           5.6.40-1.143.amzn1   amzn-updates
php70-mysqlnd.x86_64                           7.0.33-1.32.amzn1    amzn-updates
php71-mysqlnd.x86_64                           7.1.33-1.43.amzn1    amzn-updates
php72-mysqlnd.x86_64                           7.2.26-1.19.amzn1    amzn-updates
php73-mysqlnd.x86_64                           7.3.13-1.22.amzn1    amzn-updates
rsyslog-mysql.x86_64                           5.8.10-9.26.amzn1    amzn-main
ruby-mysql.x86_64                              2.8.2-1.11.amzn1     amzn-main

[ec2-user@ip-172-31-29-127 phplaravel]$ sudo yum install -y php73-mysqlnd
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
--> Running transaction check
---> Package php73-mysqlnd.x86_64 0:7.3.13-1.22.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch        Version                 Repository         Size
================================================================================
Installing:
 php73-mysqlnd      x86_64      7.3.13-1.22.amzn1       amzn-updates      336 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 336 k
Installed size: 812 k
Downloading packages:
php73-mysqlnd-7.3.13-1.22.amzn1.x86_64.rpm                 | 336 kB   00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : php73-mysqlnd-7.3.13-1.22.amzn1.x86_64                       1/1
  Verifying  : php73-mysqlnd-7.3.13-1.22.amzn1.x86_64                       1/1

Installed:
  php73-mysqlnd.x86_64 0:7.3.13-1.22.amzn1

Complete!

[ec2-user@ip-172-31-29-127 phplaravel]$ php artisan migrate


  [Illuminate\Database\QueryException]
  SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_s
  chema.tables where table_schema = homestead and table_name = migrations)



  [PDOException]
  SQLSTATE[HY000] [2002] Connection refused


[ec2-user@ip-172-31-29-127 phplaravel]$

RDS(DBサーバ)と接続する準備は整ったのでまたキャプチャー取り始めます(笑)

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

Laravelのアプリケーションをherokuへデプロイしてみた

Laravelをherokuへデプロイする際の手順

簡単な流れはこんな感じ

  1. Herokuアカウントの作成
  2. applicationの新規作成
  3. Heroku CLIのインストール
  4. プロジェクトのディレクトリに必要なファイルを作成する
  5. PostgreSQLの使用
  6. 各種環境変数の設定
  7. artisanコマンドの実行
  8. 画像はbase64エンコード
  9. debugを無効にしてproductionモードへ

アカウント作成

下記URLよりアカウントを作成する
https://signup.heroku.com/login

aplicationの新規作成

  • アカウント作成後はapplicationを作成
  • create new appを選択

スクリーンショット 2019-09-21 22.29.19.png

  • App nameを今回はfugaapplicationとする
  • Create appで作成完了 スクリーンショット 2019-09-21 22.30.52.png

Heroku CLIインストール

# herokuインストール
$ brew tap heroku/brew && brew install heroku

# 下記コマンドでのインストールは公式非推奨
$ npm install -g heroku

# バージョン確認
$ heroku --version

herokuへログイン

https://devcenter.heroku.com/articles/heroku-cli#getting-started

  • 下記コマンドを打つと何かkeyを打つように問われるのでenterを押すとログイン認証のブラウザが開く、loginボタンを押してログイン完了
$ heroku login

プロジェクトのディレクトリに必要なファイルを作成する

heroku Procfileを作成

  • プロジェクトディレクトリまで移動し、直下にProcfileファイルを作成する
  • 作成したProcfileを編集する
# ファイル作成
$ touch Procfile

# ファイル編集
$ vi Procfile

#  iでINSERTモードにし、下記内容を書き込む
$ web: vendor/bin/heroku-php-apache2 public/

# escでINSERT終了し、:wqで保存して閉じる

必要に応じてgitにコミット&プッシュする

$ git add -A .
$ git commit -m "Add Procfile"
$ git push heroku master
  • herokuとgithubを連携し、Automatic deploysを許可しておけば、githubへのプッシュで一日に一回自動でデプロイされるようになる

PostgreSQLを用意

アドオンの追加

  • herokuのアドオンのHeroku Postgresの無料プラン(HobbyDev)を利用する
    • Resourcesタブからアドオンを検索し、追加する

68747470733a2f2f692e696d6775722e636f6d2f474f4b6268666b2e706e67.png

  • herokuへログインし、ターミナル上で追加することもできる
$ heroku login

# 無料プランでDBを作成
$ heroku addons:create heroku-postgresql:hobby-dev

# アドオンが有効になったか確認
$ heroku pg:wait

環境変数設定

heroku 環境変数の確認

  • ローカル環境では.envファイルを設定していたが、herokuでは.envファイルを修正することなく、heroku用に環境設定することができる
# ログインした状態で設定状況を確認する
$ heroku login

# 全部の環境変数のキー:値を知りたい時
$ heroku config

# キーが分かるときその値のみ知りたい時
$ heroku config:get DATABASE_URL

DATABASE用環境変数の設定

  • Heroku Postgresのアドオンを追加した時点で自動でDATABASE_URLをkeyとして環境変数が保存される
  • DATABASE_URLの値に基づき、それぞれの変数を設定する
# DB情報を確認
$ heroku config:get DATABASE_URL
# 出力結果
postgres://<ユーザ名>:<パスワード>@<ホスト>:5432/<DB名>

# この出力結果に基づき、次のように設定する
DB_CONNECTION: pgsql
DB_DATABASE : <DB名>
DB_HOST : <ホスト>
DB_USERNAME : <ユーザ名>
DB_PASSWORD : <パスワード>

## 環境変数設定するときのコマンド
$ heroku config:set DB_HOST=hostname

# コマンド実行後の実際の出力
postgres://tyfcuncgcimlpf:2d08062454345434dfsf3434eefa76dbcf868a543w454345454b@ec2-54-541-543-544.compute-1.amazonaws.com:5432/dfiiks15434543
DB_CONNECTION:     pgsql
DB_DATABASE:       dfiiks15434543
DB_HOST:           ec2-54-541-543-544.compute-1.amazonaws.com
DB_USERNAME:       tyfcuncgcimlpf
DB_PASSWORD:       2d08062454345434dfsf3434eefa76dbcf868a543w454345454b
  • 画面上で、環境変数を追加することもできる

    • 追加したアドオンの画面を開いてsettingタグのDatabase CredentialsでDB情報を確認できる 68747470733a2f2f692e696d6775722e636f6d2f4932677a7142432e706e67.png
    • herokuの画面のsettingタグのConfig varsで環境変数を柄できる 68747470733a2f2f692e696d6775722e636f6d2f7a4741313055512e706e67.png

HerokuのPostgreSqlへの接続方法

下記コマンドで接続できる

# 接続
$ heroku pg:psql DATABASE_URL

# テーブル一覧表示
$ DATABASE=> \d

  • ローカルでのセットアップができていない場合エラー文が出力される
    • セットアップ方法は別途Postgressqlを確認
# error 
▸ The local psql command could not be located. For help installing psql, see
▸ https://devcenter.heroku.com/articles/heroku-postgresql#local-setup

マイグレーション

  • herokuでのDB環境の設定ができてからマイグレーションを行う

herokuマイグレーションコマンド

# マイグレーションとシーディングを実行
$ heroku run php artisan migrate --seed

# (マイグレーションをやり直したい場合)
$ heroku run php artisan migrate:refresh --seed

Class 'Faker\Factory' not found エラーが出たとき

$ composer require fzaninotto/faker

この後マイグレーションで解決

画像はbase64エンコード

  • 画像はstorageへの画像ファイル生成をして保存し、そのリンクをDBに格納していたが、herokuではファイルの生成が行えない、画像バイナリデータをDBに直接入れて対応する
    1. 画像バイナリを入れるカラム作成
    2. 画像バイナリを取得しbase64エンコードしてDBに格納
    3. base64の画像を表示

https://team-lab.github.io/skillup/step2/image_document.html
https://qiita.com/RitaChan/items/d59001430f50789c570f

画像を保存するカラムの型を変更

  • 画像のリンクを保存していたカラムに対して、カラムの方を変更し、エンコードした長文を保存できるようにする
    • マイグレーションファイルを作成し、string型からlongText型へ変更
$ php artisan make:migration change_{カラム名}_to_{テーブル名} --table={テーブル名}

マイグレーションファイル例

    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
          $table->longText('profile_img')->default('')->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
          $table->dropColumn('profile_img');
          $table->string('profile_img')->nullable()->change(); 
        });
    }

画像を表示するview変更例

phpで書いた場合

// 変更前
<img class="c-img" src="/storage/profile_images/{{ $user->id }}.jpg" alt="プロフィール画像">

// 変更後
<img class="c-img" src="data:image/png;base64,{{ $user->profile_img }}" alt="プロフィール画像">

vueで表示している場合

// 変更前
<img class="c-img" v-if="message.profile_img !== null" v-bind:src="'/storage/profile_images/' + message.from_user_id + '.jpg'" alt="プロフィール画像">

// 変更後
<img class="c-img" v-bind:src="'data:image/png;base64, '+ message.profile_img" alt="プロフィール画像">

Controller変更例

// 変更前
$user->profile_img = $request->profile_img->storeAs('public/profile_images', Auth::id() . '.jpg');

// 変更後
$user->profile_img = base64_encode(file_get_contents($request->profile_img));

以上で、DBにはエンコードされた長い文字列が保存され、表示されるようになる。

アプリの情報を設定する

下記コマンド実行で設定完了

# デバッグを有効にする
$ heroku config:set DEBUGBAR_ENABLED=true

# キーを設定する
$ heroku config:set APP_KEY=$(php artisan key:generate --show)

メール送信設定

mailtrapやgmailのSMTPを使用する際の設定値の確認はこちらを参考に

heroku メール用環境変数の設定

  • DB設定と同様にheroku用に環境設定する
  • 平文で送らないとエラーになるので、MAIL_PORTは587番
# ログインした状態で確認する
$ heroku login

# 全部の環境変数のキー:値を知りたい時
$ heroku config

# キーが分かるときその値のみ知りたい時
$ heroku config:get DATABASE_URL

# 環境変数のセッティング例
$ heroku config:set DB_HOST=hostname

# 設定内容(2019/8/23)現在
MAIL_DRIVER:       smtp
MAIL_FROM_ADDRESS: hogehoge.info@gmail.com
MAIL_FROM_NAME:    hogeapplication
MAIL_HOST:         smtp.gmail.com
MAIL_PASSWORD:     wcfghjkljhnsn
MAIL_USERNAME:     hogehoge.info@gmail.com

本番環境へ

デバッグモードを無効に

$ heroku config:set DEBUGBAR_ENABLED=false

production modeにする

  • 下記コマンドでコンソールに出力されていたvue deveropmentの文字も消える
$ npm run production
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel ユーザー登録、ログイン・ログアウト機能(Seederでユーザー生成)

ユーザー登録、ログイン・ログアウト機能生成

ユーザー登録やログイン・ログアウト機能はコントローラーやビューを作る必要があるが、
Laravelではコマンド一つで作成可能

$ php artisan make:auth

すると下記ファイルが自動生成される

resources
|- views
   |- home.blade.php
   |- layouts
   |  |- app.blade.php
   |- auth
      |- passwprds
      |  |-email.blade.php
      |  |-reset.blade.php
      |- login.blade.php
      |- register.blade.php
      |- verify.blade.php
app
|- Http
   |- Controllers
   |  |- HomeController.php
   |- Auth
      |- ForgotPasswordController.php
      |- LoginController.php
      |- RegisterController.php
      |- ResetPasswordController.php
      |- VerificationController.php   

また、ルーティングroutes/web.phpに次のように追加される

Route::get('/', function () {
    return view('welcome');
});

// 以下が追加される内容
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
  • ルーティングではgetメソッドでサーバー側に要求が来た時の処理を定義する
  • 第一引数にuri(ドメイン以降のurl)を指定し、第二引数に処理を指定する
  • Auth::routes();では、vendor/laravel/framework/src/Illuminate/Routing/Router.phpで定義されたルーティングが読み込まれる

生成されたコントローラとビューとエンドポイントの関係

生成されたエンドポイントとそれぞれのコントローラーとビューの役割と関係は次の通り

URI(エンドポイント) HTTPメソッド コントローラー名@アクション名 機能名
/home GET HomeController@index マイページ表示
/register GET RegisterController@showRegistrationForm ユーザー登録表示
/register POST RegisterController@register ユーザー登録
/login GET LoginController@showLoginForm ログイン表示
/login POST LoginController@login ログイン
/logout POST LoginController@logout ログアウト
/password/reset GET ForgotPasswordController@showLinkRequestForm パスワードリマインダー画面
/password/email POST ForgotPasswordController@sendResetLinkEmail パスワードリマインド
/password/reset/{token} GET ForgotPasswordController@showResetForm パスワード再入力画面
/password/reset POST ForgotPasswordController@reset パスワード更新
/email/verify GET VerificationController@show Eメール認証画面
/email/verify/{id} GET VerificationController@verify Eメール認証
/email/resend GET VerificationController@resend Eメール認証メール再送信

※Eメール認証機能を使うには別途カラムが必要であったり、設定が必要となる

seederを使ってダミーデータを入れる

LaravelにはDBのテーブルにダミーデータを入れる機能がある

  • ログイン機能を作る際にユーザー登録機能が存在しない時にうまく動くかテストする際に使用したりする
# seederファイル作成
$ php artisan make:seeder {適当な名前}
# usersテーブルにダミーデータを追加したい場合の例
$ php artisan make:seeder UsersTableSeeder

データを1つずつ入れる場合

/database/seeds配下にUsersTableSeeder.phpが作成される

作成されたファイルの関数は空なので自分で追加する

<?php

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;  // 関数でDBクラスを使えるように
use Carbon\Carbon;  // 関数でCarbonクラスを使えるように

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // ここが空なので以下を追加する
        DB::table('users')->insert([
            // ランダムもしくは特定の文字列を入れることも可能
            'name' => str_rand(10),  
            'email' => str_rand(10).'@example.com',
            // bcryptでハッシュ化
            'password' => bcrypt('password'),  
            // Carbonクラスのnowで現在時刻になる
            'created_at' => Carbon::now(),  
            'updated_at' => Carbon::now(),
        ]);
    }
}

Seederクラスを書き上げたら、Composerのオートローダを再生成するために、dump-autoloadコマンドを実行する必要がある

$ composer dump-autoload

seederファイルを編集したら次のコマンドで実行する
実行するとseederで定義したダミーデータが作成される
実行するたびにダミーデータが一つずつ生成される

$ php artisan db:seed --class=UsersTableSeeder

ダミーデータを削除し、DB再生成は次のコマンド

$ php artisan migrate:refresh --seed

データをまとめていっぱい作りたい場合は下記参考

Laravel ダミーデータ登録(seeder, factory, faker)

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

laravel-debugbarの利用

概要

laravel-debugbarを導入することで、変数内の値やリクエスト内容、レスポンス内容などその他様々な情報をブラウザ上で操作しながら確認することができるようになる便利なバーが出現する

install

$ cd [適用するプロジェクト]
$ composer require barryvdh/laravel-debugbar

サービスプロバイダーとファサードの追加

config/app.php
'providers' => [
    Barryvdh\Debugbar\ServiceProvider::class,
],

'aliases' => [
    'Debugbar' => Barryvdh\Debugbar\Facade::class,
]

envファイルの設定

.env
APP_DEBUG=true

本番環境へデプロイ

  • envファイルを変更するだけで良い
.env
APP_DEBUG=false
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel-debugbarを使えば様々な値をブラウザ上で簡単に確認できる

概要

laravel-debugbarを導入することで、変数内の値やリクエスト内容、レスポンス内容などその他様々な情報をブラウザ上で操作しながら確認することができるようになる便利なバーが出現する

install

$ cd [適用するプロジェクト]
$ composer require barryvdh/laravel-debugbar

サービスプロバイダーとファサードの追加

config/app.php
'providers' => [
    Barryvdh\Debugbar\ServiceProvider::class,
],

'aliases' => [
    'Debugbar' => Barryvdh\Debugbar\Facade::class,
]

envファイルの設定

.env
APP_DEBUG=true

本番環境へデプロイ

  • envファイルを変更するだけで良い
.env
APP_DEBUG=false
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel よく使うクエリビルダと複雑なwhere

DBファサードのテーブルメソッドを使ってクエリ文を作成してデータを取得する

DBファサードは select、update、insert、delete、statementのクエリタイプごとにメソッドが用意されている

https://readouble.com/laravel/5.5/ja/queries.html
データベースクエリビルダはスラスラと書ける(fluent)便利なインターフェイスで、クエリを作成し実行するために使用します。アプリケーションで行われるほとんどのデーターベース操作が可能で、サポートしている全データベースシステムに対し使用できます。

LaravelクエリビルダはアプリケーションをSQLインジェクション攻撃から守るために、PDOパラメーターによるバインディングを使用します。バインドする文字列をクリーンにしてから渡す必要はありません。

よく使うクエリビルダ

select() 基本的なクエリの実行

$item = DB::select('SELECT * FROM items');

DBからのデータ取得

基本 get()でテーブルのすべてのデータを取得

$items = DB::table('テーブル名')->get();

// Eloquent(Model)を作成するとDB::table()を使わなくて良くなる
// Itemモデルを作った場合
$items = App\Item::get();

// AppネームスペースでItemをuseで追加しておくとシンプルに書ける
use App\Item;
$items = item::get();

first() 最初のひとつだけ取得

// たくさん得られるデータから最初のひとつだけ取得
// (並べ替えしていない場合idの昇順$id=1)
$items = Item::first();

take() 個数を指定して取得

// 複数取得できる中から個数を選択して取得
$items = Item::take(3)->get();

find() idを指定して取得

$item = Item::find(2);

chunk() 指定の件数ごとに取得

// 2件ごとにデータを纏めて取得6件あった場合[2, 2, 2]のようなまとまりになる
$items = Item::chunk(2);

select() カラム指定で取得

// nameのみ取得する場合
$items = Item::select('name')->get();
// 複数指定する場合(idとnameを取得する場合)
$items = Item::select('id', 'name')->get();

value() 指定したかカラムの値を1つ取得

// where()で指定したレコードを取得する
// id=2,3の2つのレコードの場合where('id', [2, 3])
// valueでカラムを絞り込んで値を取得する
$items = Item::where('id', [2, 3])->value('name');
// この例ではid=2,3のnameカラムの値を1つ取得する
// このように配列でレコードを2つ指定しても値は1つしか取れない

pluck() 指定したカラムの値すべて取得

// 指定したカラム名のデータをすべて取得
$items = Item::pluck('name');
// 第二引数にkeyを指定してkey=>valueの形で2つ取得できる
$items = Item::pluck('name', 'id');
    // $id => $name

where(), orWhere 該当するデータだけ取得

// 'name'カラムが'名前1'のレコードを取得したい場合
$items = Item::where('name', '名前1')->first();

// A and B
// 'name'カラムが'名前1'でかつ'name'カラムが'名前2'のレコードを取得したい場合
$items = Item::where('name', '名前1')->where('name', '名前2')->first();

// A or B
// 'name'カラムが'名前1'のレコードもしくは'name'カラムが'名前2'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->orWhere('name', '名前2')
        ->first();

// (A and B) or C (andが強いため特別な処理は必要ない)
// 'name'カラムが'名前1'かつ'name'カラムが'名前2'のレコードもしくは'name'カラムが'名前3'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->where('name', '名前2')
        ->orWhere('name', '名前3')
        ->first();

// A or (B and C)
// 'name'カラムが'名前1'かつ'name'カラムが'名前2'のレコードもしくは'name'カラムが'名前3'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->orWhere('name', '名前2')
        ->where('name', '名前3')
        ->first();

// A and (B or C)
// 'name'カラムが'名前1'のレコード、かつ'name'カラムが'名前2'もしくは'name'カラムが'名前3'のレコードを取得したい場合
$items = Item::where('name', '名前1')
        ->where(function($query) {
        $query->where('name', '名前2')
              ->orwhere('name', '名前3')
        })
        ->first();

// (A and B) or (C and D)
$items = Item::where('name', '名前1')
        ->where('name', '名前2')
        ->orWhere(function($query) {
        $query->where('name', '名前2')
              ->where('name', '名前3')
        })
        ->first();

// (A or B) and (C or D)
$items = Item::where(function($query) {
        $query->orWhere('name', '名前1')
              ->orWhere('name', '名前2')
        ->where(function($query) {
        $query->orWhere('name', '名前2')
              ->orWhere('name', '名前3')
        })
        ->first();

// 関数を使う場合で変数を使いたい場合はuseを使う
$items = Item::where('name', '名前1')
        ->where(function($query)use($user) {
        $query->where('name', '$user->name')
              ->orwhere('name', '$user->name')
          })
        ->first();

ログインユーザー情報の取得

$user = Auth::user();
// ログインにかかわらず登録ユーザー情報を取得する場合は
$user = User::get();

(補足)tinkerで認証をする場合

// そのままだと次のようになる
>>> Auth::user()
 => null
// 認証が済んでないのでidを指定してログインする
>>> auth()->loginUsingId(1);
// id確認も可能
>>> auth()->id()
 => 1
>>> Auth::user()
 => //

リレーション先のデータを取得

with() リレーション先と一緒に取得

// ItemがbelongsTo('App\Content');とする
$items = Item::with('contents')->get();


App\Order::join('users', 'orders.user_id', '=', 'users.id')->get()

取得したデータの保存

save() 既存データと異なれば保存

データが同じであれば保存されずupdated_atも更新されない

$item = Item::find(1)
$item->name = $request->name;
$item->save();

save前に更新されたか確認

isDirty()を使うことで変更されているかどうか確認ができる
変更されていればtrue、されていなければ(更新せずに更新ボタンが押された場合)falseを返す

$order = App\Order::find(1);
$order->price = 50000; // 変更前20000の場合
$order->isDirty() // 返り値true
$order->save();

update() 既存データを確認せず更新保存

データが同じであっても上書きされupdated_atも更新される

$item = Item::find(1)->update(['name' => $request->name]);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

世はまさに Web アプリケーションフレームワーク戦国時代?

Web アプリケーションフレームワークを選ぶ基準って、人それぞれ、色々とあるとは思いますが、やっぱり流行も気になってしまうのが Web エンジニア心というものではないでしょうか?

それに、よく使われているということは、

  • 当然、フレームワークとしての成熟度は高いはずですし、
  • サードパーティのライブラリも充実していて、
  • 比較的、Web サイトや書籍などから得られる情報量も多い

と、考えられます。

初めて Web アプリを作成するという人はもちろん、

ある程度、知識のある方でも、軽い気持ちで新しいフレームワークを学んでみたいというのであれば、流行りに乗っておくのが無難かもしれません。

というわけで、ここでは、

  • Ruby
  • Python
  • PHP
  • JavaScript

で、実装されている「 人気の Web アプリケーションフレームワーク 」について、興味本位でまとめてみましたので、良かったら何かの参考にでもして頂ければ幸いです。

Ruby on Rails vs. Sinatra

Ruby の Web アプリケーションフレームワークと言えば、Ruby on Rails ですね。

GitHub のスター数は、現在、45k となっています。

https://github.com/rails/rails

異論は認めますが、比較するとしたら、Sinatra くらいしかないでしょうか?

GitHub のスター数は、現在、10.9k となっています。

https://github.com/sinatra/sinatra

Google トレンド のグラフを見ると、Ruby の Web フレームワーク自体、徐々に人気が下がってきているようでもありますが、あとで他の言語とも比較してみましょう。

Django vs. Flask vs. Tornado

Google トレンド によると、Python では、やっぱり Django が人気ですが、Flask の人気もかなり上がってきているように見えます。

単純に考えれば、Python 自体の人気が急上昇していることが要因でしょうか。

GitHub のスター数はと言うと、現在、Django が 47.1k で、Flask が 48.8k となっています。

https://github.com/django/django
https://github.com/pallets/flask

比較対象として、もう一つ、Tornado という Web フレームワークを挙げておきましょう。

こちらは、GitHub のスター数が、現在、18.8k となっています。

https://github.com/tornadoweb/tornado

Laravel vs. Symfony vs. CodeIgniter

PHP では、Laravel が人気を博しているようですね。

GitHub のスター数は、現在、57.5k となっています。

https://github.com/laravel/laravel

何となくのイメージですが、昔から、Web アプリ作成のフレームワークと言えば PHP みたいなところもあるので、やはり定番なのでしょうか。

今回、Laravel と比較するのは、SymfonyCodeIgniter です。

GitHub のスター数は、現在、Symfony が 22.7k で、CodeIgniter が 17.9k となっています。

https://github.com/symfony/symfony
https://github.com/bcit-ci/CodeIgniter

Google トレンド によると、他のフレームワークの人気がなくなってきていると言うよりは、純粋に Laravel が強すぎる感じですかね。

Vue.js vs. React vs. AngularJS

JavaScript に関しては、そもそも他の言語と同列に扱っていいのか、ちょっと微妙なところもあるかもしれませんが、

ともかく、Google トレンド のグラフを見ると、React の勢いが凄いです。

GitHub のスター数は、現在、143k となっています。

https://github.com/facebook/react

もちろん、GitHub のスター数が全てではありませんし、条件が同じとも言い難いですが、他の言語の Web フレームワークと、桁が違いますね。笑

しかし、スター数で言えば、実は、Vue.js の方が多く、現在、157k となっています。

https://github.com/vuejs/vue

また、AngularJS はと言うと、GitHub のスター数は、現在、59.6k となっていますが、それでも多いので、全く侮れません。

https://github.com/angular/angular.js

ただ、Google トレンド によると、Vue.js の人気も、上がってはいるのですが、他の二つに比べるとちょっと低すぎるように見えます。

一体、どういうことでしょうか?

ここへきて、この人気調査?の信憑性が危ぶまれる事態とも言えますが、これは「 一つの指標だけに囚われてはいけない 」ということの好例、ということにしておきましょう。

Ruby on Rails vs. Django vs. Laravel vs. React

まぁ、Google トレンド については、ものによって、キーワードの指定や検索の仕方で結果が大きく変わってしまう場合もあるので、自分でも試してみることをオススメします。

ちなみに、今回は、国やカテゴリなどは絞り込まず、同形異義語を排除するために、プログラミング言語名を一緒に検索してみました。

他にも、人気を判断するために、こんな指標があるよ!というような情報がありましたら、是非、教えて頂ければと思います。

話は逸れましたが、最後に、懲りもせず Google トレンド で、

  • Ruby on Rails
  • Django
  • Laravel
  • React

の、各言語で人気らしい Web フレームワークの比較もしてみましょうか。

結果は、こんな感じになりました。
スクリーンショット 2020-02-09 0.00.30.png
URL は、https://trends.google.co.jp/trends/explore?date=2016-01-01%202019-12-31&q=rails%20ruby,django%20python,laravel%20php,react%20javascript です。

このグラフによれば、Rails の人気が下がってきて、Django と Laravel は少しずつ上昇し、React は急上昇したことにより、

世はまさに「 Web アプリケーションフレームワーク戦国時代 」に突入した!と、言えるのかもしれません。笑

特にどの言語に媚びることもない、こんな平和な?結論が、果たしてあり得るのかどうかはともかく、たとえこれが事実だったとしても、ここを分岐点として、これから、どのフレームワークが生き残っていくのか、頭一つ抜けるのか、見ものではありますよね。

しばらくしたら、また調べてみたいと思います。

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

Laravel パスワードリマインダーメールを日本語化してみる

パスワードリマインダーカスタマイズ・日本語化

  • make:authコマンドとメールSMTP設定が済むとパスワードリマインダー機能が使える
    • デフォルトでは英語となっているため日本語化の設定が必要

(追記)

@ShibuyaKosuke さんのコメントでresources/lang/ja.json の編集のみでメールでも日本語化が可能なことを教えて頂きました。こちらの方がいいと思います。

ja.json
{
    "Hello!": "こんにちは",
    "Reset Password Notification": "パスワード・リセット通知",
    "You are receiving this email because we received a password reset request for your account.": "アカウントのパスワードリセットリクエストを受け取ったため、このメールを受信して\u200B\u200Bいます。",
    "Reset Password": "パスワードをリセット",
    "This password reset link will expire in :count minutes.": "このパスワードリセットリンクの有効期限は :count 分です。",
    "If you did not request a password reset, no further action is required.": "パスワードのリセットを要求しなかった場合、それ以上のアクションは不要です。"
}

送信されるメールの日本語化

  • notificationのカスタマイズ
  • App\Userにカスタマイズしたnotificationメソッドを追加し、定義をオーバーライド

notificationのカスタマイズ

$ php aritsan make:notification CustomResetPassword

app/Notifications/CustomResetPassword.phpが生成される
中身を次のように変更する

app/Notifications/CustomResetPassword.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;

class CustomResetPassword extends Notification
{
  use Queueable;

  /**
   * Create a new notification instance.
   *
   * @return void
   */

  public $token;

  public function __construct($token)
  {
    $this->token = $token;
  }

  /**
   * Get the notification's delivery channels.
   *
   * @param  mixed  $notifiable
   * @return array
   */
  public function via($notifiable)
  {
    return ['mail'];
  }

  /**
   * Get the mail representation of the notification.
   *
   * @param  mixed  $notifiable
   * @return \Illuminate\Notifications\Messages\MailMessage
   */
  public function toMail($notifiable)
  {
    return (new MailMessage)
      ->from('admin@example.com', config('app.name'))
      ->subject('パスワード再設定')
      ->line('下のボタンをクリックしてパスワードを再設定してください。')
      ->action('パスワード再設定', url(config('app.url') . route('password.reset', $this->token, false)))
      ->line('もし心当たりがない場合は、本メッセージは破棄してください。');
  }

  /**
   * Get the array representation of the notification.
   *
   * @param  mixed  $notifiable
   * @return array
   */
  public function toArray($notifiable)
  {
    return [
      //
    ];
  }
}

App\Userのオーバーライド

App\Userに次の内容を追加する

App\User
// 追加する内容
use App\Notifications\CustomResetPassword;


class User extends Authenticatable
{
  use Notifiable;

  // 追加する内容
  public function sendPasswordResetNotification($token)
  {
      $this->notify(new CustomResetPassword($token));
  }

(補足)送信された再設定用のリンクが開けない場合

  • .envファイルのAPP_URLがうまく設定できていない場合がある
    • APP_URL=http://192.168.0.1:3000 などのようにつながるドメイン・ポート番号に設定する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 複雑なバリデーションでフォームリクエストクラスを使用する

概要

  • フォーム送信されたときにバリデーションメソッドを使って各項目が適正であるかをチェックする
  • Laravelでデフォルトで用意されたバリデーション内容では満足できない複雑なバリデーションを必要とするとき、コントローラへの記載ではコントローラーが肥大化し、可読性が落ちる。そこで、フォームリクエストクラスというバリデーションロジックをコントローラから分離させる。

内容

今回はFFromRequestクラスを継承したSampleRequestクラスを生成し、コントローラからのバリデーション分離を試みる。

フォームリクエストクラスの生成

下記コマンドを実行

$ php artisan make:request SampleRequest

するとapp/Http/Request下にSampleRequest.phpが生成される

app/Http/Request
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SampleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

生成されたファイルを次のように編集していく

  • authorize()ではtrueを返す
    • authorize()はユーザ権限や認証系のバリデーションを定義する
    • 特に必要ない場合はfalseを返す
  • rules()にバリデーション内容を記載する
app/Http/Request
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SampleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
          'name' => 'required|string|max:255',
          'gender' => 'required',
          'age' => 'required|integer',
          'file' => 'required|file|image|max:10000',
          'comment' => 'required',
        ];
    }
}

コントローラ側の設定

フォームリクエスト使用に伴い、下記2点を追加する

  • 生成したSampleRequestをuseする
  • アクション名の引数にSampleRequsetを渡す
    • フォーム内容がアクションへ渡される際にバリデーション処理が実行され、渡ってきた際にはバリデーション処理が完了している状態である
app/Http/Controllers/SampleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\SampleRequest;  // 追記

class ValiController extends Controller
{
  public function update(SampleValiRequest $request)  // 引数にフォームリクエスト渡す
  {
        return view('sample');
 }
}

カスタムエラーメッセージ設定

  • フォームごとに独自のエラーメッセージを表示したい場合、フォームリクエストクラスに追記するだけで実装できる
  • messages()を作成し、その中にエラーメッセージ内容を記述する
    • name.ruleの規則で記述する
app/Http/Request
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SampleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
          'name' => 'required|string|max:255',
          'gender' => 'required',
          'age' => 'required|integer',
          'file' => 'required|file|image|max:10000',
          'comment' => 'required',
        ];
    }

    // 追記内容
    /**
     * エラーメッセージのカスタマイズ
     * @return array
     */
    public function messages()
    {
      return [
        'name.required' => '名前を入力してください',
        'name.string' => '名前は文字列で入力してください',
        'name.max' => '名前は255文字以内で入力してください',
        'gender.required'  => '性別を選択してください',
        'age.required'  => '年齢を選択してください',
        'age.integer'  => '年齢は数字で入力してください',
        'file.required'  => 'ファイルを選択してください',
        'file.file'  => 'ファイルのアップロードに失敗しました',
        'file.image'  => 'アップロード可能な画像は「jpg」「png」「bmp」「gif」「svg」です',
        'file.max'  => 'アップロードするファイルは10MBまでです',
        'comment.required' => 'コメントを入力してください',
      ];
    }

}

独自バリデーションの追加

  • 上記に引き続きフォームリクエスト内に追記する形で実装
  • withValidator()メソッドに処理内容を記載することでバリデーション追加をすることが可能
    • validatorの中に
app/Http/Request
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SampleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
          'name' => 'required|string|max:255',
          'gender' => 'required',
          'age' => 'required|integer',
          'file' => 'required|file|image|max:10000',
          'comment' => 'required',
        ];
    }

    /**
     * エラーメッセージのカスタマイズ
     * @return array
     */
    public function messages()
    {
      return [
        'name.required' => '名前を入力してください',
        'name.string' => '名前は文字列で入力してください',
        'name.max' => '名前は255文字以内で入力してください',
        'gender.required'  => '性別を選択してください',
        'age.required'  => '年齢を選択してください',
        'age.integer'  => '年齢は数字で入力してください',
        'file.required'  => 'ファイルを選択してください',
        'file.file'  => 'ファイルのアップロードに失敗しました',
        'file.image'  => 'アップロード可能な画像は「jpg」「png」「bmp」「gif」「svg」です',
        'file.max'  => 'アップロードするファイルは10MBまでです',
        'comment.required' => 'コメントを入力してください',
      ];
    }


 // 追記内容

  /**
   * 独自処理を追加する
   * @param $validator
   */
  public function withValidator($validator)
  {
    $validator->after(function ($validator) {
      if (
        strtotime(date('H:i:s')) >= strtotime('21:00:00')
        ||
        strtotime(date('H:i:s')) <= strtotime('09:00:00')
      ) {
        $validator->errors()->add('field', '投稿できるのは9時から21時までです。');
      }
    });
  }

}

参考

https://www.ritolab.com/entry/41

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

Laravel バリデーションで他のカラムを比較する

laravel バリデーションでカラム名を使用する

  • バリデーションで最大値と最小値のバリデーションをするときカラム名を使用したい時がある
    • max_priceの入力値をmin_priceよりも大きいように指定したいような場合
      • この内容は拡張しなくても使用できるようになっているかも??(2019/8/19)
$request->validator([
'min_price' => 'required|integer|digits_between:1,4',
'max_price' => 'required|integer|digits_between:1,4|min:min_price',
]);

しかし、min:では整数値しか受け付けないため、カラム名を使用できるように拡張が必要となる

カスタムバリデーションの作成

サービスプロバイダーの作成

# コマンド実行すると次のサービスプロバイダのファイルが生成される
$ php artisan make:provider ValidatorServiceProvider

生成されたファイルのboot()メソッドの編集

app/Providers/ValidatorServiceProvider.php
<?php

namespace App\Providers;

use Validator;
use App\Services\CustomValidator;
use Illuminate\Support\ServiceProvider;

class ValidatorServiceProvider extends ServiceProvider
{
  /**
   * 全アプリケーションサービスの登録
   *
   * @return void
   */
  public function register()
  {
    //
  }

  /**
   * 全アプリケーションサービスの初期起動
   *
   * @return void
   */
  public function boot()
  {
    Validator::resolver(function ($translator, $data, $rules, $messages) {
      return new CustomValidator($translator, $data, $rules, $messages);
    });
  }
}

作成したサービスプロバイダーを設定ファイルに追記

config/app.php
'providers' => [
    ...

    App\Providers\ValidatorServiceProvider::class,

    ...

minの拡張

  • Illuminate\Validation\Concerns\ValidatesAttributes::validateMinの内容をオーバーライドして拡張
Illuminate\Validation\Concerns\ValidatesAttributes
    /**
     * Validate the size of an attribute is greater than a minimum value.
     *
     * @param  string  $attribute
     * @param  mixed   $value
     * @param  array   $parameters
     * @return bool
     */
    public function validateMin($attribute, $value, $parameters)
    {
        $this->requireParameterCount(1, $parameters, 'min');

        return $this->getSize($attribute, $value) >= $parameters[0];
    }
  • App\Services\CustomValidator.phpを作成し、\Illuminate\Validation\Validator を継承してオーバーライドする内容を書く
App\Services\CustomValidator.php
<?php

namespace App\Services;

class CustomValidator extends \Illuminate\Validation\Validator
{
  /**
   * 最小値 min
   * @param string $attribute
   * @param string $value
   * @param array $parameters 0 => 比較するカラム名
   * @return true
   */
  public function validateMin($attribute, $value, $parameters)
  {
    if (
      !is_numeric($parameters[0]) &&
      !is_null($val = $this->getValue($parameters[0]))
    ) {
      $parameters[0] = $val;
    }

    return parent::validateMin($attribute, $value, $parameters);
  }
}

バリデーションのカラム名の日本語化

  • resources/lang/ja/validation.phpの100行目あたりに、Custom Validation Attributesという項目がある。
    /*
    |--------------------------------------------------------------------------
    | カスタムバリデーション属性名
    |--------------------------------------------------------------------------
    |
    | 以下の言語行は、例えば"email"の代わりに「メールアドレス」のように、
    | 読み手にフレンドリーな表現でプレースホルダーを置き換えるために指定する
    | 言語行です。これはメッセージをよりきれいに表示するために役に立ちます。
    |
    */

    'attributes' => [
    // 追記する内容
            'email'=>'メールアドレス',
            'password'=>'パスワード',
            'name'=>'名前',
            'category'=>'種別',
            'min_price'=>'最低価格',
            'max_price'=>'最高価格',
            'deadline'=>'募集期限',
            'detail'=>'詳細',
            'title'=>'タイトル',
            'price'=>'価格',
    ],

を引数に入れた場合の日本語化

  • カラム名を引数に取れるように拡張した min, max で英文字のカラム名が展開できるのは、数値が与えられたときの標準の展開がそのまま適用されており、対応が必要

valueの値を日本語にする

resources\lang\ja\validator.php
'min'=> [
    'numeric' => ':attributeには、:min以上の数字を指定してください。',
]
  • CustomValidatorのコンストラクタを追記し、最終的には次のようにする
App\Services\CustomValidator.php
<?php

namespace App\Services;

class CustomValidator extends \Illuminate\Validation\Validator
{

  public function __construct($translator, $data, $rules, $messages = [])
  {
    parent::__construct($translator, $data, $rules, $messages);

    // $message    = カスタムエラーメッセージの内容
    // $attribute  = エラーが発生したキー名
    // $rule       = バリデーションのルール 例:required
    // $parameters = 場合によって変わるが、digitsであれば文字数などが配列で入る
    //
    // クロージャなので、$dataを値渡ししてあげる。
    // $data = リクエストデータが入る
    $replacer = function ($message, $attribute, $rule, $parameters) use ($data) {

      // $message 内の :values を $data[$attribute] に置換する
      return str_replace(':'.$rule, $data[$attribute], $message);
    };
      // 表示させる文字列を入れることもできる
      return str_replace(':'.$rule, '最低価格', $message);
    };

    // 上記のクロージャを適応するルール
    $this->addReplacers([
      "min" => $replacer,
    ]);
  }

  /**
   * 最小値 min
   * @param string $attribute
   * @param string $value
   * @param array $parameters 0 => 比較するカラム名
   * @return true
   */
  public function validateMin($attribute, $value, $parameters)
  {
    if (
      !is_numeric($parameters[0]) &&
      !is_null($val = $this->getValue($parameters[0]))
    ) {
      $parameters[0] = $val;
    }

    return parent::validateMin($attribute, $value, $parameters);
  }
}

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