LoginSignup
7
7

More than 5 years have passed since last update.

Laravelで簡単なページを作成するまで

Last updated at Posted at 2019-01-05

はじめに

今年はほぼ間違いなくPHPしかもLaravelを触ることになるので、簡単なサイトを作成することにしました。
環境構築から一通りやることがあるので、覚えておくためにまとめておきます。

前提

Windowsで作業してるので、MacやLinux使っている人には不要な作業も記載しています。
一通り記載するつもりですが、記載が漏れて不要な作業が書かれていたらごめんなさい。

環境

PHP 7.2
Laravel Framework 5.7.19
Postgres 11.1(psql 9.5.11)
Docker for Windows 2.0.0.0-win81 (29211)
nginx 1.15.8

今回作るもの

色々とやろうとしましたが、簡単なサイトなら何かの一覧表示すればいいやということで、データベースに登録した本一覧が画面に表示されるまでを作ることにしました。

Laravelの環境構築

まずはLaravelを使用出来るようにする必要があります。
今回はlaradockを使用して楽させてもらいます。

上で記載した環境は書いた当時(2019/01/03)のlaradockで使用されているバージョンそのままです。

laradockのclone

Githubにありますので、cloneしてもってきます。
場所はどこでも大丈夫です。

git clone https://github.com/Laradock/laradock.git

laradockの環境設定

Docker for Windows + Postgres用の設定変更をするのとコンテナ起動のためにフォルダ内に移動します。

cd laradock

そして設定ファイルのサンプルをベースに書き換えるために設定ファイルをコピーしておきます。

cp env-example .env

laradockのデフォルトはmysqlを使用する設定となっていてpostgresがインストールされないため、されるように以下の設定をtrueに変更します。

WORKSPACE_INSTALL_PG_CLIENT=true

次にdocker-compose.ymlも修正します。

修正の前にpostgres用のnamed volumeを作成しておきます。
postgresの永続化はwindowsだと上手くいかずnamed volumeを作成してそこを指定するというのが一般的です。

docker-compose.yml
docker create volume --name postgres_db

named volumeを作成したらdocker-compose.ymlのpostgresのvoluesを作成したnamed volumeに変更します。
なんとなく必要のないdocker-entrypoint-initdb.dの設定も書き換えていますが、気にしないでください。

docker-compose.yml
postgres_db:/var/lib/postgresql/data
./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d

後、なぜかelasticsearchのvolume設定が変でエラーになってしまうので、使用しませんが修正しておきます。

docker-compose.yml
elasticsearch:/usr/share/elasticsearch/data
${DATA_PATH_HOST}/elasticsearch:/usr/share/elasticsearch/data

最後にvolumesの使用設定を一番下に追加して終わりです。

docker-compose.yml
## volumes
volumes:
  postgres_db:
   external: true

次にlaradockでnginxを使用することになるので先回りして設定を変更しておきます。
laradock/nginx/sites/default.confrootを今回作成するパスに変更します。
app01という名前で作成するつもりなので、下記のような設定にしていますが、自身の作成したい名前に合わせてフォルダ名は入力してください。

やる際はconfのバックアップを取得した方が無難です。

root /var/www/app01/public;

コンテナ起動

必要なことは終わったのでコンテナを起動します。

docker-compose up -d nginx postgres

初回は色々と時間かかるので、待ってる間は適当に暇をつぶしてください。

Laravelプロジェクトの生成

コンテナ起動後はコンテナ内に入ってLaravelプロジェクトを生成します。
laradockはworkspaceという全ての操作が可能なコンテナが用意されるので、ここから操作していきます。

docker-compose exec workspace bash

コンテナに入ったら/var/www配下にいますので、composerを使用してプロジェクトを生成します。
composerはデフォルトで入っているので、何もせず使用してOKです。

root@cdcd5245e1ef:/var/www# composer create-project laravel/laravel app01

プロジェクトの生成確認

プロジェクトが生成された確認はhttp://localhost/にブラウザからアクセスすれば分かります。
nginxの設定次第なので、URLは適宜読み替えてください。

Laravelのデフォルト画面が出てくれば無事に生成することが出来ました。

データベースの設定

プロジェクトの生成が終わると、cloneしたフォルダと同階層にapp01が出来ています(laradockのデフォルト設定)。
そこが実際に実装を行っていくプロジェクトです。

まずはデータベースの設定を行っていきます。
プロジェクトのrootフォルダに.envファイルがありますので、開いてDBの設定を入れておきます。
ここで記載しているのはlaradockのデフォルト設定で作成した情報となりますので、違う設定でコンテナ作った人は読み替えてください。

注意点としては、DB_HOSTはpostgresだとpostgresにしないと駄目だということぐらいです。

DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

もう一つ/config/database.phpも同じ感じで修正します。
見れば分かると思うので割愛します。
schemaについてはこちらのファイルでしか設定できないので、publicが嫌な場合はコンテナ入って作って設定を変えてください。

今回はプロダクトじゃなくて自分の勉強用なので変更せずいきます。

Laravel標準認証機能を使用する

今回は認証機能を使用する必要はないのですが、折角なので機能確認目的でデフォルトの認証機能について作成しておきます。
マイグレーションついでにデータベースの設定が正しいかもチェックしておきます。

root@cdcd5245e1ef:/var/www/app01# php artisan make:auth
root@cdcd5245e1ef:/var/www/app01# php argisan migrate

マイグレーションに成功したらこんな感じでユーザー系のテーブルが生成されます。

root@cdcd5245e1ef:/var/www/app01# psql -U default -h postgres
Password for user default:
psql (9.5.12, server 11.1)
WARNING: psql major version 9.5, server major version 11.
         Some psql features might not work.
Type "help" for help.

default=# \d
                List of relations
 Schema |       Name        |   Type   |  Owner
--------+-------------------+----------+---------
 public | migrations        | table    | default
 public | migrations_id_seq | sequence | default
 public | password_resets   | table    | default
 public | users             | table    | default
 public | users_id_seq      | sequence | default

Index画面を変更する

一覧を表示するためIndex画面を流用して書き換えを行います。

デフォルトのRoutingはroutes/web.phpに書いているので、そこでIndexページのphpファイルが
resources/views/welcome.blade.php
であることが確認できます。
新しく作成するのも面倒なので、このままこれを使いまわしたいと思います。

デザインに関しては今回はある程度適当に作ってしまおうと思うので、デフォルトのwelcome.blade.phpを親にして@yield('content')にコンテンツを記述するように修正をします。
ついでにタイトルとかスタイルも修正しています。。

修正後はviews/layouts/index.blade.phpとして保存します。

ちなみにhtmlとかcss周りはそれなりに表示出来ればいいやーぐらいで作成しています(今回の勉強したい主題ではないので)。

index.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Simple library</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Nunito', sans-serif;
                font-weight: 200;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .title {
                font-size: 84px;
            }

            .content {
                text-align: center;
            }
            .m-b-md {
                margin-bottom: 30px;
            }

            @yield('style')
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            @if (Route::has('login'))
                <div class="top-right links">
                    @auth
                    @else
                        <a href="{{ route('login') }}">Login</a>

                        @if (Route::has('register'))
                            <a href="{{ route('register') }}">Register</a>
                        @endif
                    @endauth
                </div>
            @endif

            <div class="content">
                <div class="title m-b-md">Books</div>
                <div>
                    @yield('content')
                </div>
            </div>
        </div>
    </body>
</html>

中身も適当に作ります。
今回はページャーについては作成しないで、取れたもの全て表示するとします。
いったん仮で作成したもので表示確認だけ行って次の作業に移ります。

welcome.blade.php
@extends('layouts.index')

@section('style')
ul li {
    list-style: none;
    float:left;
    display: table-cell;
}

.item-list {
    width : 20%;
}

.item-title {
    font-size : 14px;
}

.item-img {
    width : 150px;
    height : 150px;
}
@endsection

@section('content')
<div>
    <ul>
        <li class="item-list">
            <p class="item-title">タイトル</p>
            <img src="" class="item-img">
        </li>
    </ul>
</div>
@endsection

Index用のControllerの作成

データベースからデータを取得しないと成り立たないので、Contollerを作成していきます。

Controllerの生成

Contollerはコマンドから生成できるので、コンテナに入って生成します。

root@cdcd5245e1ef:/var/www/app01# php artisan make:controller IndexController

Routingの変更

今まで直接viewを返していましたが、Controller経由で返却するようroutes/web.phpのRoutingを変更します。

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

Contollerの仮実装

まだ貸すための本が取得出来ない状態なので、いったんwelcome.blade.phpを返却するよう仮実装を行います。

IndexController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class IndexController extends Controller
{
    public function index()
    {
        return view('welcome');
    }
}

データを取得できるようにする

migrate用ファイルの生成

まずはテーブルを生成するための実装を行っていきます。
migration用のファイルもコマンドから生成します。

php artisan make:migration create_books_table

データベース定義の作成

作成したファイルに定義を追加していきます。
今回はタイトルと画像URLを保存するとします。

作成したphpファイルに定義を追加してコンテナからmigrateして完了です。

カラムは単純ですが一応not null制約とindexを付けてみます。

2018_12_29_145459_create_books_table.php
    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->increments('id');
            $table->text('title')->nullable(false);
            $table->text('img_url')->nullable(false);
            $table->timestamps();
            $table->index('title');
        });
    }

pgadmin上でnot null制約とindexがきちんと付与されているかだけチェックしておきます。

-- Table: public.books

-- DROP TABLE public.books;

CREATE TABLE public.books
(
    id integer NOT NULL DEFAULT nextval('books_id_seq'::regclass),
    title text COLLATE pg_catalog."default" NOT NULL,
    img_url text COLLATE pg_catalog."default" NOT NULL,
    created_at timestamp(0) without time zone,
    updated_at timestamp(0) without time zone,
    CONSTRAINT books_pkey PRIMARY KEY (id)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE public.books
    OWNER to "default";

-- Index: books_title_index

-- DROP INDEX public.books_title_index;

CREATE INDEX books_title_index
    ON public.books USING btree
    (title COLLATE pg_catalog."default")
    TABLESPACE pg_default;

Controllerからデータを全部取得する

テーブルに適当なデータを入れておいたとします。
(自分は確認用にアマゾンから適当な商品名と画像リンクを使わせていただきました)

そこからデータを取得をするべくControllerの修正を行います。

修正点はuse Illuminate\Support\Facades\DB;を追加したのとviewへの変数受け渡しとして['books' => DB::table('books')->get()]を追加した2点です。

IndexController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class IndexController extends Controller
{
    public function index()
    {
        return view('welcome', ['books' => DB::table('books')->get()]);
    }
}

viewで取得したデータを表示できるようにする

viewの方も動的に出力できるよう修正します。

修正点は@foreachの追加とタイトル、URLの埋め込みをそれぞれしています。

welcome.blade.php
@extends('layouts.index')

@section('style')
ul li {
    list-style: none;
    float:left;
    display: table-cell;
}

.item-list {
    width : 20%;
}

.item-title {
    font-size : 14px;
}

.item-img {
    width : 150px;
    height : 150px;
}
@endsection

@section('content')
<div>
    <ul>
        @foreach ($books as $book)
        <li class="item-list">
            <p class="item-title">{{ $book->title }}}</p>
            <img src="{{$book->img_url}}" class="item-img">
        </li>
        @endforeach
    </ul>
</div>
@endsection

さいごに

Laradock導入からHTML除けば2時間くらいでここまで来ることが出来ています(HTMLに小1時間ほど悩んだ)。
PHPは全然触ったことないけど(現時点で3時間くらい)、書き方覚えればなんとかいけそうなぐらい簡単でした。

これから使うプロダクトも増えてくるでしょうし、そんなに難しくないので一度は触っておいた方が良いかもしれません。

参考にしたサイト

https://qiita.com/J_Shell/items/695a30fd38444d065ae5
https://gist.github.com/yano/64c07ee81db24985fe8f6091cace503d
https://readouble.com/laravel/5.7/ja/

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7