20200103のlaravelに関する記事は6件です。

Laravelで簡単なメモアプリを作る(2)~データの取得と保存~

はじめに

Laravelとは、Webに特化したPHPフレームワーク。セキュリティ対策(CSRF対策など)もこれでできます。MVCアーキテクチャを採用しています。今回は、データベースの接続とデータの取得と保存をしていきたいと思います。

Laravelで簡単なメモアプリを作る(1)~Viewの作成と表示~
Laravelで簡単なメモアプリを作る(3)~データの更新と削除~

今回の目標物

スクリーンショット 2019-12-31 11.25.14.png

スクリーンショット 2019-12-31 11.25.26.png

データ取得の流れ

スクリーンショット 2020-01-01 19.00.07.png

スクリーンショット 2020-01-01 19.00.16.png

スクリーンショット 2020-01-01 19.00.23.png

データベースの作成

データベースの作成

phpMyAdminを開く。Newを押して、新しくdatabaseを作成する。今回は、memoAppという名前のデータベースを作成する。

スクリーンショット 2020-01-01 19.05.57.png

データベースの接続

.envに、データベースの情報を記述する。DB_DATABESEには、データベースの名前を入れる。MAMPを使っている人は、デフォルトでユーザー名、パスワード共にrootなので特に設定していなければ、下の内容をそのままコピー&ペーストして良い。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=memoApp
DB_USERNAME=root
DB_PASSWORD=root

モデルの作成

ターミナルまたは、PowerShellを開き、cdコマンドでmemoAppまで移動し、下のコマンドを打ち込む。

$ php artisan make:model Memo

先ほど作成したモデルにDBのテーブル情報を記述する。

app/Memo.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Memo extends Model
{
    // table名を指定
    protected $table = 'memo';

    // カラムを指定
    protected $fillable = [
        'id', 'title', 'content'
    ];

    // created_atを使わない場合はfalseを指定する。
    public $timestamps = false;
}

テーブルの作成

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

ターミナルまたはpowerShellを開いて、cdコマンドでmemoAppまで移動し、下のコマンドを打つ。

$ php artisan make:migration create_memo_table

先ほど、生成したファイルにカラムの情報を記述する。

id : bigInt型
title : string型 24桁
content: string型 60桁

database/migrations/2019_12_12_114638_create_memo_table.php
<?php

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

class CreateMemoTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('memo', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title', 24);
            $table->string('content', 60);
        });
    }

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

seederの作成

ターミナルまたはpowerShellを開いて、cdコマンドでmemoAppまで移動し、下のコマンドを打つ。

$ php artisan make:seeder MemoTableSeeder
database/seeds/MemoTableSeeder.php
<?php

use Illuminate\Database\Seeder;

use App\Memo;

class MemoTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('memo')->delete(); //最初に全件削除

        Memo::create([
            'title' => '12/13 laravel勉強会', 'content' => 'データの読み取りと追加をやりました。'
        ]);

        Memo::create([
            'title' => '12/6 laravel勉強会', 'content' => 'Viewの表示をしました。'
        ]);
    }
}
database/seeds/DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        Model::unguard();

        $this->call('MemoTableSeeder');

        Model::reguard();
    }
}

マイグレーションとSeederの反映

phpMyAdminにマイグレーションとSeederを反映させる。ターミナルまたはpowerShellを開いて、cdコマンドでmemoAppまで移動し、下のコマンドを打つ。

$ php artisan migrate --seed

phpMyAdminを開いて、反映されているかどうか確認する。

ちなみに、エクセル形式で表すとこんな感じになる。

スクリーンショット 2020-01-01 19.26.08.png

データの取得

データをViewに渡す

app/Http/Controllers/MemoController.phpに、データをViewに渡すメソッドを記述する。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit()
    {
        return view("submit");
    }
}

とりあえずresources/views/home.blade.phpの適当なところに<div>{{$memos}}</div>を入れて、表示を確認してみよう。

$memosの中身が、id,title,contentの要素を持つオブジェクトの配列になっていることがわかる。

スクリーンショット 2020-01-03 15.34.31.png

resources/views/home.blade.phpの適当なところに以下のコードを追加してみる。

<div>{{$memos[0]->id}}</div>
<div>{{$memos[0]->title}}</div>
<div>{{$memos[0]->content}}</div>

ループを使わずにこんな感じで表示してみよう。

スクリーンショット 2020-01-03 15.41.46.png

home.blade.php
<tbody>
  <tr>
    <td class="left">{{$memos[0]->title}}</td>
    <td><a href="{{ route('submit')}}">編集</a></td>
    <td><a>削除</a></td>
  </tr>
  <tr>
    <td class="left">{{$memos[1]->title}}</td>
    <td><a href="{{ route('submit')}}">編集</a></td>
    <td><a>削除</a></td>
  </tr>
</tbody>

これをループを用いて、記述するとこんな感じになる。

resources/views/home.blade.php
<tbody>
   @foreach ($memos as $memo)
     <tr>
       <td class="left">{{$memo->title}}</td>
       <td><a href="{{ route('submit')}}">編集</a></td>
       <td><a>削除</a></td>
     </tr>
   @endforeach
</tbody>

bladeファイルはhtmlファイルと違って、@を使うことで直接、条件分岐やループ文を記述することができる。中括弧で囲む必要がないが@endif@endforなどで閉じてやる必要がある。

詳細画面にもデータを渡す

URLからメモのidを受け取れるようにする。URLを‘/submit/{id?}’にすることで、idという変数をコントローラに渡すことができる。

routes/web.php
<?php

/*
|--------------------------------------------------------------------------
| 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('/', function () {
    return view('sample');
});

Route::get('/home', 'MemoController@showHome')->name('home');

Route::get('/submit/{id?}', 'MemoController@showSubmit')->name('submit');

リンクを押すと、URLにidを含んだページに飛べるようにする。href="{{ route('submit', ['id' => $memo->id])}}"とすることで、URLにidを渡すことができる。

resources/views/home.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        color: white;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .card {
        margin-top: 40px;
    }

    .left {
        width: 70%;
    }

    .submit {
        position: absolute;
        top: 10px;
        right: 20px;
    }
</style>
@endsection

@section('content')
<div class="card" style="width: 100%;">
    <div class="card-header">
        メモ一覧
        <a href="{{ route('submit')}}" class="submit">メモを追加</a>
    </div>

    <table class="table">
        <tbody>
            @foreach ($memos as $memo)
            <tr>
                <td class="left">{{$memo->title}}</td>
                <td><a href="{{ route('submit', ['id' => $memo->id])}}">編集</a></td>
                <td><a>削除</a></td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

コントローラーの関数の引数に、URLの変数を渡せる。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit($id = 0)
    {
        if ($id != 0) {
            $memo = Memo::where('id', $id)->get()->first();
        } else {
            $memo = (object) ["id" => 0, "title" => "", "content" => ""];
        }
        return view("submit", ['memo' => $memo]);
    }
}

コントローラから送られてきたデータを、Viewに埋め込む。

resources/views/submit.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .container {
        margin-top: 40px;
    }
</style>
@endsection

@section('content')
<form>
    <div class="form-group">
        <label for="title">タイトル</label>
        <input type="text" class="form-control" id="title" name="title" value="{{$memo->title}}">
    </div>
    <div class="form-group">
        <label for="content">内容</label>
        <input type="text" class="form-control" id="content" name="content" value="{{$memo->content}}">
    </div>
    <a href="{{ route('home')}}" class="btn btn-primary">戻る</a>
    <button type="submit" class="btn btn-success">追加</button>
</form>
@endsection

データの保存

postを使って、データをコントローラに送る。

resources/views/submit.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .container {
        margin-top: 40px;
    }
</style>
@endsection

@section('content')
<form method="POST" action="{{ route('submit', ['id' => $memo->id])}}">
    @csrf
    <div class="form-group">
        <label for="title">タイトル</label>
        <input type="text" class="form-control" id="title" name="title" value="{{$memo->title}}">
    </div>
    <div class="form-group">
        <label for="content">内容</label>
        <input type="text" class="form-control" id="content" name="content" value="{{$memo->content}}">
    </div>
    <a href="{{ route('home')}}" class="btn btn-primary">戻る</a>
    <button type="submit" class="btn btn-success">追加</button>
</form>
@endsection

MemoControllerに、Viewから送られてきたデータをデータベースに保存するメソッドを記述する。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit($id = 0)
    {
        if ($id != 0) {
            $memo = Memo::where('id', $id)->get()->first();
        } else {
            $memo = (object) ["id" => 0, "title" => "", "content" => ""];
        }
        return view("submit", ['memo' => $memo]);
    }

    public function postSubmit(Request $request, $id = 0)
    {
        $title = $request->input('title');
        $content = $request->input('content');
        if ($id == 0) {
            Memo::create([
                'title' => $title,
                'content' => $content
            ]);
        }
        return redirect()->route('home');
    }
}

web.phpに以下の内容を記述する。

routes/web.php
<?php

/*
|--------------------------------------------------------------------------
| 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('/', function () {
    return view('sample');
});

Route::get('/home', 'MemoController@showHome')->name('home');

Route::get('/submit/{id?}', 'MemoController@showSubmit')->name('submit');

Route::post('/submit/{id?}', 'MemoController@postSubmit')->name('submit');

今回はここまで。次回は、データの編集と削除をしたいと思います。

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

laravel5.4でPOSTしたページからGETのページに遷移したい

困りごと

環境面の制約があって今更Laravel5.4で色々作成しています。
文献も多いのである程度順調に作成自体は進んでいるのですが、
思わぬところで嵌って今ネットの海を迷走中です。

C:\Git\php-mariadb-docker\php\www\public\qa>php artisan --version
Laravel Framework 5.4.36

それはタイトルにも上げた
POSTしたページからGETのページにredirectしたい
というものです。

関係ありそうなところだけのrouteに加工してますが、こんな感じのroute定義

C:\Git\php-mariadb-docker\php\www\public\qa>php artisan route:list
+--------+----------+-----------------------+--------------------+----------------------------------------------------------+--------------+
| Domain | Method   | URI                   | Name               | Action                                                   | Middleware   |
+--------+----------+-----------------------+--------------------+----------------------------------------------------------+--------------+
|        | GET|HEAD | entry/{id}            | entry.show         | App\Http\Controllers\EntryController@show                | web          |
|        | PUT      | entry/{id}            | entry.update       | App\Http\Controllers\EntryController@update              | web          |
|        | GET|HEAD | entry/{id}/edit       | entry.edit         | App\Http\Controllers\EntryController@edit                | web          |
+--------+----------+-----------------------+--------------------+----------------------------------------------------------+--------------+

具体的には
entry.edit(GET)からentry.updateへPOSTします。
entry.updateではDBへの登録処理を行った後に、entry.show(GET)ページにリダイレクトさせたい
という事になります。

entry.updateのソースはこんな感じ

EntryController.php
    public function update(Request $request, $id){
        $entry = Entry::findOrFail($id);

        $entry->parent = $request['parent'];
        $entry->name = $request['name'];
        $entry->department = $request['department'];
        $entry->email = $request['email'];
        $entry->tel = $request['tel'];
        $entry->title = $request['title'];
        $entry->content = $request['content'];
        $entry->category = $request['category'];
        $entry->status = $request['status'];

        $entry->save();

        return redirect('entry.show', ['id' => $id]); 
    }

このredirect('entry.show', ['id' => $id]);の部分、
エラーメッセージ(MethodNotAllowedHttpException)を見てるとどうやらPOSTで渡している様子

これをGETで'entry.show'へリダイレクトさせる方法はありませんでしょうか?

ネットの海を徘徊しながら、コメントが付くことを祈って(笑)

宜しくお願いいたします♪

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

【AWS】Elastic BeanstalkでLinux 用 Windows サブシステムを使用せずにLaravelアプリケーションをデプロイする

Elastic BeanstalkでLinux 用 Windows サブシステムを使用せずにLaravelアプリケーションをデプロイ方法です。
本手順では、代わりに、フリーの圧縮・解凍ソフトを使用しています。

環境

  • PHP:バージョン7.3(Elastic Beanstalk)
  • Laravel:バージョン6.9.0
  • OS:Windows10(ローカル)

手順

Elastic Beanstalk への Laravel アプリケーションのデプロイ | aws
に従って実施します。
タイトルの件を以下に、補足事項としてまとめます。

補足事項

手順では、Linux 用 Windows サブシステムを使用するとありますが、以下の通り実行すればインストール不要です。

1. Laravelプロジェクトの作成

ローカル環境でコマンドプロンプトを起動して、任意のパスでコマンドを実行し、Laravelプロジェクト作成します。
こちらは、手順と同じコマンドで大丈夫です。
※今回は、プロジェクト名を「testLaravelApp」としました。

> composer create-project --prefer-dist laravel/laravel testLaravelApp

2. zipファイルの作成

1で作成したプロジェクトを圧縮します。
Windowsにおいては、デフォルトではzipコマンドを実行できないため、GUIベースで圧縮します。
私はフリーの圧縮・解凍ソフト7-Zipを使用しました。

注意点

圧縮実行時には、以下の点に気をつけてください。

1. デプロイしたいプロジェクト直下で圧縮する

公式の手順(コマンド)からもわかる通り、デプロイしたいプロジェクト直下で圧縮作業を実施します。
プロジェクトをそのまま圧縮してデプロイすると以下のようなエラーが出てしまい、ページへのアクセスもできないので要注意!

ダッシュボード

image.png

ヘルス

image.png

調べたところ、対象プロジェクトをそのまま圧縮すると余計なディレクトリが含まれてしまうから、とのこと。
【参考】
Following services are not running: proxy @ AWS — after Laravel re-config | stack overflow

2. vendorは対象外とする

公式の手順にも記載ありますが、念のため。


上記1, 2を考慮しての7-Zipでの圧縮は以下の通りとなります。
image.png

そうすると、同フォルダ内に対象のLaravelプロジェクトと同じ名称のzipファイルができるので、それをアップロード・デプロイすればOK!

image.png

オマケの注意点

こちらも公式手順に記載ありですが、ドキュメントのルートを
/public
とするのを忘れずに☆
image.png

無事、デプロイ→ページ表示できました!

ダッシュボード

image.png

ページ

image.png

参考

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

Homestead上のWebサイトをngrokで公開する

ngrok とは

ngrokとはローカルサーバーをインターネット上へ公開することのできるサービスです。

Web開発の現場では、Webhookのテストによく使われていると思います。

https://ngrok.com/

基本的な使い方

http://localhost のWebサイトを指定する場合であれば、次のように起動します。

ngrok http 80

Homestead を用いた使い方

Hostヘッダを指定することで、Laravel Homestead上のWebサイトを公開することができます。

ngrok http <homestead_host_ip>:<port> -host-header=<homestead_domain>

https://ngrok.com/docs#http-host-header

HomesteadのIPアドレスが 192.168.10.10http://homestead.test のWebサイトを指定する場合であれば、次のように起動します。

ngrok http 192.168.10.10:80 -host-header=homestead.test

ngrok の設定ファイルを使った起動方法

設定ファイルに接続先を定義することで、次のようにコマンドを簡易化することができます。

ngrok start homestead

https://ngrok.com/docs#config

デフォルトの設定ファイルを上書きする場合は次のファイルを編集してください。

OS X /Users/example/.ngrok2/ngrok.yml
Linux /home/example/.ngrok2/ngrok.yml
Windows C:\Users\example\.ngrok2\ngrok.yml

トンネル名 homesteadanother を定義する例です。

ngrok.yml
  homestead:
    proto: http
    addr: 192.168.10.10:80
    host_header: homestead.test
  another:
    proto: http
    addr: 192.168.10.10:80
    host_header: another.test

ngrok start homesteadngrok start another が使えるようになりました。

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

[Vue + Laravel] build & deployした際に画面が真っ白に

環境

  • Laravel Framework 5.7.28
  • vue : 2.6.10
  • vuex : 3.1.2
  • vue-router : 3.1.3
  • Chrome (79.0.3945.88(Official Build)(64 ビット))
  • VSCODE

vue-cliは使っていません

現象

レンタルサーバーにbuild & deployした際にブラウザ上でも一切エラーは発生していないが、ページが真っ白になってしまう

手順

build

npm run prod

試したこと

色々ググって関係ありそうな以下を試してみました

  • vue.config.jsでpublicPathを設定する

 そもそもこのファイル自体が存在しないので新規で作ってみましたが無駄でした。。。

  • vue-routerのindex.jsにてhistory modeを外してみた

 ページが表示された!!!!!!!!
 ただ、これだとURLに「#」が入ってしまう

結論

vue-routerでbaseオプションを指定する

baseにはpublicまでのpathを設定

const router = new Router({
    mode: 'history',
    base: '/app/public',
})

上記の設定でページが表示されるようになりました

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

Laravel6 備忘録 −ユーザー認証(Auth)−

ユーザー認証

Laravel6からはLaravel5.9以前から使えていたphp artisan make:authコマンドが使えないため、以下の手順で設定する

環境

バージョン
PHP 7.2.9
Laravel 6.8.0
Node 8.11.4
npm 6.4.0
terminal
## phpのバージョン
vagrant@homestead:~/code/myapp$ php -v
PHP 7.2.9-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Aug 19 2018 07:16:54) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.9-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with blackfire v1.22.0~linux-x64-non_zts72, https://blackfire.io, by Blackfire

## laravelのバージョン確認
vagrant@homestead:~/code/myapp$ php artisan --version
Laravel Framework 6.8.0

## nodeの存在確認
vagrant@homestead:~/code/myapp$ node -v
v8.11.4

## npmの存在確認
vagrant@homestead:~/code/myapp$ npm -v
6.4.0

手順

vagrantでsshログインしてアプリケーションのルートフォルダへ移動

laravel作成時のマイグレーションファイルをmagrateする
(auth用のuserテーブルのマイグレーションファイルはすでに作成されている)

terminal
vagrant@homestead:~/code/myapp$ php artisan migrate

パッケージのlaravel/uiをcomposerで追加する

terminal
vagrant@homestead:~/code/myapp$ composer require laravel/ui --dev

vue,react,bootstrapから利用するものに合わせてインストールする

terminal
## 認証機能を利用する場合は--auth必須
## 認証機能を利用しない(単純にUIにvue,react,bootstrapを利用したい場合)は--authは不要

## vueの場合
vagrant@homestead:~/code/myapp$ php artisan ui vue --auth

## reactの場合
vagrant@homestead:~/code/myapp$ php artisan ui react --auth

## bootstrapの場合
vagrant@homestead:~/code/myapp$ php artisan ui bootstrap --auth

これでpackage.jsonに指定したものが追加される

package.json
{
  "devDependencies": {
        "axios": "^0.19",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "jquery": "^3.2",
        "laravel-mix": "^4.0.7",
        "lodash": "^4.17.13",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.20.1",
        "sass-loader": "7.*",
        "vue": "^2.5.17", // 追加された
        "vue-template-compiler": "^2.6.10" // 追加された
    }
}

npmで必要なパッケージをインストールする

terminal
vagrant@homestead:~/code/myapp$ npm install
vagrant@homestead:~/code/myapp$ npm run dev

完了

注意

導入以前に、デフォルトで作成されているresource/js/app.jsresource/sass/app.scssを移動していたり削除していたりすると、上記作業中にエラーが発生する
これらはvue,react,bootstrapを導入する際にresource/sass/app.scss,resurece/js/app.jsが必須ファイルであるため

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