#AWSのCloud9でLaravelを使ってみる
PHPのワークフレームであるLaravelを使ってみたいと思い、色々と学んだことを健忘録がてら、まとめようと思います。
特にAmazon Linux2に関しては、調べてもナレッジが少なかったので、他の方の参考になれば幸いです。
##AWS上でCloud9を起動し、環境設定を行う
###AWSにサインイン
AWSからコンソールにサインインする。
案内に従って、マネジメントコンソールが表示されるまで進む
###environmentを構築する
environment=プロジェクトの構築環境を作る。
ますは、「create environment」を選択し、
環境設定を行う。
「Instance type」は無料枠の場合、「t2.micro」を選択する。
また、30分ごとに接続が切れるように設定しないと、気付いたら高額の請求がされる可能性があるので注意。
##Laravelの環境設定
environmentの構築が終わると、下のような画面が表示されます。
一番したのwindowはtarminal windowであり、以下もコードをこのwindowに書き込んでいきます。
*コマンド入力の最中に質問されることがありますが、全て'y'と答えれば問題ないです。
###PHPセットアップ
まずはPHP7.2のセットアップ
$ sudo amazon-linux-extras install php7.2=stable
$ sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml
MaryaDBの設定
MySQLの上位互換であるMaryaDBを構築
MaryaDBの設築
$ sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2
####MariaDBのインストール
$ sudo yum install -y mariadb-server
####MariaDBの起動と初期設定
$ sudo systemctl start mariadb
$ sudo mysql_secure_installation
上記のコマンド入力後に初期設定についていくつか質問されるので、以下のように答えます。
新しいパスワードを入力する時、入力の文字は表示されないので注意してください。
<初回設定の入力項目>
Set root password? [Y/n] y
New password: root
Re-enter new password: root
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y
####MaridaDBの自動起動を有効化
MaridaDBが自動で起動するように設定。
$ sudo systemctl enable mariadb
$ sudo systemctl is-enabled mariadb
###Composerインストール
PHPのライブラリを管理してくれるComposerをインストールする。
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/bin/composer
$ composer
###Laravelインストール
composerを利用してcmsという作業ディレクトリを作成しLaravelをインストールします。
$ composer create-project laravel/laravel cms 6.* --prefer-dist
今後の作業はこのcmsディレクトリで行います。
###サーバーの起動とLaravelの起動
####BuiltInサーバーを起動:動作確認
サーバーを起動するために、先ほど作成した作業ディレクトリであるcmsに移動
$ cd cms
下記コマンドを入力しサーバーを起動します。
$ php artisan serve --port=8080
Cloud9の画面上部の緑の起動ボタンの左側PreviewボタンからPreview Running Applicationをクリック
右下に画面が起動してLaravelの文字が確認できたら、Laravelのインストール成功
新しくpop upしたwindowの右上にある「pop up into new window」を選択し、新規タブでLaravelのデモ画面を表示
サーバーを起動しているtarminalはそのままに、新しいtarminalを立ち上げておく。
上記までの流れでLaravelの環境設定は完了です。
##データベースの作成
新しく立ち上げたターミナルで作業ディレクトリであるcmsに移動
$ cd cms
下記コマンドを入力していき、c9というデータベースを作成
$ mysql -u root -p
パスワードの「root」を入力
root [Enterキー]
c9というデータベースを作成
create database c9;
うまく作成されたか確認
show databases;
下記のようにtarminalに表示されれば成功
データベースから退場
exit;
##Laravelプロジェクト初期設定
###.envファイルの更新
上記のように「Show Hidden Files」を設定し.envファイルが確認
.envファイルの下記該当部分を内容を下記のように更新し保存
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=c9
DB_USERNAME=root
DB_PASSWORD=root
###Composerアップデートコマンド実行
更新内容を反映するために、サーバーを一度停止。
サーバーを動かしているtarminalで"control+c"を入力し、サーバーを停止。
その後下記を入力し、composerをupdate。
sudo composer update
途中で質問が出るが、yesで回答。
その後、再度サーバーを起動。
$ php artisan serve --port=8080
###/app/Providers/ AppServiceProvider.php ファイルを修正
app→Providers→AppServiceProvider.phpと進み、下記のように記載。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema; //この行を追加
use Illuminate\Support\Facades\URL; //この行を追加
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191); //この行を追加
URL::forceScheme('https'); //この行を追加
}
}
##phpMyAdmin設定
###cms階層からpublicフォルダに移動
$ cd public
###phpMyAdminのzipをダウンロード
$ wget https://files.phpmyadmin.net/phpMyAdmin/4.8.3/phpMyAdmin-4.8.3-all-languages.zip
###zipファイルを解凍
$ unzip phpMyAdmin-4.8.3-all-languages.zip
###cms階層に戻る
$ cd ..
###phpMyAdminを確認する
publicフォルダ内に「phpMyAdmin-4.8.3-all-languages」フォルダが作成される。
フォルダ名が長いので「phpMyAdmin」に変更。
「Preview」で開かれているURLの最後に「phpMyAdmin/index.php」をつけてEnterキーを押す。
* URL例: https://******.cloud9.us-east-1.amazonaws.com/phpMyAdmin/index.php
phpMyAdmin画面が表示されたら: ユーザー名・パスワードともに「root」を入力してログイン
ログインできればOK
##お気に入りYouTube管理アプリを実装する
以下のコマンドは作業ディレクトリのcmsで行ってください。
###Laravel/uiの実装
今後のUIを整えるために必要なパッケージをインストールします。
インストールできると、ログイン認証画面が簡単に実装できます。
####1. マイグレーションを実行
php artisan migrate
####2. laravel/ui パッケージをインストール
composer require laravel/ui:^1.0 --dev
####3. artisan コマンドを実行
php artisan ui vue --auth
####4. npmパッケージをインストール
npm install
####5. パッケージをビルド
npm run dev
###データベースにMoviesテーブルを作成する為のマイグレーションを作成
####1. artisanコマンドでマイグレーション作成
$ php artisan make:migration create_movies_table --create=movies
####2. database/migrationsの直下のmovies_table.phpに以下追記
public function up()
{
Schema::create('movies', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('item_name');
$table->text('item_url');
$table->timestamps();
});
}
####3. マイグレーション実行(テーブルの作成)
php artisan migrate
phpMyAdminでmoviesが作成されているか確認する
カラムの修正・追加時は、tableのファイルを修正・保存後に、下記コマンドでrefreshする。
$ php artisan migrate:refresh
###モデルの作成/ルーティングとviewの設定
####1.artisanコマンドでモデル作成
作成したテーブルを適宜使用するためにモデルを作成します。
このモデルに対して働きかけることで、テーブルの管理を行います。
その際に、複数形のテーブル名を単数形+大文字スタートでモデル名を設定すれば、Laravel上で自動的にリンクされます。
$ php artisan make:model Movie
####2./routes/web.phpの設定
web.phpはこのプロジェクトの設計図にあたる場所で、このプロジェクトで使用するURLを管理する場所です。
このファイルを見れば、このプロジェクトがどのように作成されているかを理解できる場所です。
まず、このweb.phpと先ほど作成したMovieモデルを接続します。
また、後ほど作成するコントローラーに機能を振り分けるための処理を記載します。
<?php
use App\Movie;
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
// 動画管理の初期画面
Route::get('/', 'MoviesController@index');
// 新「動画」を追加
Route::post('/movies', 'MoviesController@store');
// 動画を削除
Route::delete('/movie/{movie}', 'MoviesController@destroy');
//「動画」を更新画面表示
Route::get('/moviesedit/{movie}','MoviesController@edit');
//「動画」を更新処理
Route::post('movies/update','MoviesController@update');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
####4. MoviesControllerの設定。
app->Http->Controllers->MoviesController.phpに下記を追記します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Movie;
use Validator;
class MoviesController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$movies = Movie::orderBy('created_at', 'asc')->paginate(3);
return view('movies', [
'movies' => $movies
]);
}
/**
* 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)
{
//バリデーション
$validator = Validator::make($request->all(), [
'item_name' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
//以下に登録処理を記述(Eloquentモデル)
// Eloquent モデル
$movies = new Movie;
$movies->item_name = $request->item_name;
$movies->item_url = $request->item_url;
$movies->save();
return redirect('/');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit(Movie $movie)
{
return view('moviesedit', ['movie' => $movie]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request)
{
//バリデーション
$validator = Validator::make($request->all(), [
'item_name' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
// Eloquent モデル
$movies = Movie::find($request->id);
$movies->item_name = $request->item_name;
$movies->item_url = $request->item_url;
$movies->save();
return redirect('/');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Movie $movie)
{
$movie->delete(); //追加
return redirect('/'); //追加
}
}
####5. resources/views/の直下にmovies.blade.php を作成して以下を追記
動画を登録するためのUIとなるページを作成します。
UI部分はこのviewsファイルに格納します。
<!-- resources/views/movies.blade.php -->
@extends('layouts.app')
@section('content')
<!-- Bootstrapの定形コード… -->
<div class="card-body">
<div class="card-title">
<お気に入り動画入力フォーム>
</div>
<!-- バリデーションエラーの表示に使用-->
@include('common.errors')
<!-- バリデーションエラーの表示に使用-->
<!-- 動画登録フォーム -->
<form action="{{ url('movies') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- 動画のタイトル -->
<div class="form-group">
<div class="card-title">
<動画タイトル>
</div>
<div class="col-sm-6">
<input type="text" name="item_name" class="form-control">
</div>
</div>
<!-- 動画のURL -->
<div class="form-group">
<div class="card-title">
<動画URL>
</div>
<div class="col-sm-6">
<input type="text" name="item_url" class="form-control">
</div>
</div>
<!-- 動画 登録ボタン -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary">
Save
</button>
</div>
</div>
</form>
<!-- 現在の動画 -->
@if (count($movies) > 0)
<div class="card-body">
<div class="card-body">
<table class="table table-striped task-table">
<!-- テーブルヘッダ -->
<thead>
<th>動画タイトル</th>
<th>動画URL</th>
<th> </th>
<th> </th>
<th> </th>
</thead>
<!-- テーブル動画体 -->
<tbody>
@foreach ($movies as $movie)
<tr>
<!-- 動画タイトル -->
<td class="table-text">
<div>{{ $movie->item_name }}</div>
</td>
<!-- 動画URL -->
<td class="table-text">
<div>{{ $movie->item_url }}</div>
</td>
<td class="table-text">
<button type=“submit” class="btn btn-success" onclick="location.href='{{$movie->item_url}}'">動画へ</button>
</td>
<!-- 動画: 削除ボタン -->
<td>
<form action="{{ url('moviesedit/'.$movie->id) }}" method="GET">
{{ csrf_field() }}
<button type="submit" class="btn btn-primary">更新 </button>
</form>
</td>
<td>
<form action="{{ url('movie/'.$movie->id) }}" method="POST">
<form action="{{ url('movie/'.$movie->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">
削除
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
<!-- Movie: 既に登録されてる動画のリスト -->
<div class="row">
<div class="col-md-4 offset-md-4">
{{ $movies->links()}}
</div>
</div>
@endsection
####6. resources/views/の直下にmoviesedit.blade.php を作成して以下を追記
動画の内容を変更し登録するためのUIとなるページを作成します。
@extends('layouts.app')
@section('content')
<div class="row">
<div class="col-md-12">
@include('common.errors')
<form action="{{ url('movies/update') }}" method="POST">
<!-- item_name -->
<div class="form-group">
<label for="item_name">Title</label>
<input type="text" name="item_name" class="form-control" value="{{$movie->item_name}}">
</div>
<!--/ item_name -->
<!-- Save ボタン/Back ボタン -->
<div class="well well-sm">
<button type="submit" class="btn btn-primary">Save</button>
<a class="btn btn-link pull-right" href="{{ url('/') }}"> Back</a>
</div>
<!--/ Save ボタン/Back ボタン -->
<!-- id 値を送信 -->
<input type="hidden" name="id" value="{{$movie->id}}" /> <!--/ id 値を送信 -->
<!-- CSRF -->
{{ csrf_field() }}
<!--/ CSRF -->
</form>
</div>
</div>
@endsection
####7. /resources/views/common/errors.blade.phpを作成し以下を追記
誤った入力が行われた場合の処理を設定するために、commonフォルダを作成し、errors.blade.phpファイルを作成します。
@if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<div><strong>入力した文字を修正してください。</strong></div>
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
###データベース管理の設定について
データベースは、
① 登録
② 表示
③ 更新
④ 削除
の4つ機能で全て表現することができます。
そしてこれらの処理については、MoviesController.phpに記載されています。
####登録について
web.phpの中も「動画の追加部分」に'MoviesController@store'と記載することで、登録処理についてはMoviesController.php内のstore部分で行うように振り分けることができます。
public function store(Request $request)
{
//バリデーション
$validator = Validator::make($request->all(), [
'item_name' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
//以下に登録処理を記述
$movies = new Movie;
$movies->item_name = $request->item_name;
$movies->item_url = 'aaaa';
$movies->item_details = 'details';
$movies->published = '2017-03-07 00:00:00';
$movies->save();
return redirect('/');
}
####表示について
web.phpの中も「動画管理の初期画面」に'MoviesController@index'と記載することで、表示についてはMoviesController.php内のindex部分で行うように振り分けることができます。
public function index()
{
$movies = Movie::orderBy('created_at', 'asc')->paginate(3);
return view('movies', [
'movies' => $movies
]);
}
これにより、Movieモデルを介して、moviesテーブル内のデータが降順に$moviesに格納され、viewファイル内のmovies.blade.phpにデータが渡されます。
####更新について
web.phpの中も「更新画面表示」にからMoviesedit.phpに遷移し、中の処理は'MoviesController@edit'と記載することで、MoviesController.php内のedit部分で行うように振り分けることができます。
public function index()
{
$movies = Movie::orderBy('created_at', 'asc')->paginate(3);
return view('movies', [
'movies' => $movies
]);
}
その後、updateにて更新された内容が反映されます。
####削除処理について
web.phpの中の「削除」部分にあるdeleteの中に、選択された項目のidを持った変数が選択され、それが削除されるという処理をMoviesController.php内のdestoryに振り分けるという記述を行いっています。
public function destroy(Movie $movie)
{
$movie->delete(); //追加
return redirect('/'); //追加
}