Laravelは、表現力豊かで美しい構文を持つPHPのウェブアプリケーションフレームワーク。豊富なパッケージとライブラリでプログラミングの面倒なタスクが簡素化され、開発作業も捗ります。
Laravelを使ったクリエイティブプロジェクトのひとつとして、個人ブログの構築があります。今回はLaravelを使ってブログを構築し、Kinstaで公開する方法をご紹介していきます。
本記事で例として取り上げるプロジェクトのコードの全貌はこちらでご覧ください。
前提条件
これからご紹介する例では、以下を前提とします。
- ウェブサーバー(今回の例ではXAMPPを使用)
- アプリケーションのコードを公開するためのGitHub、GitLab、またはBitbucketのアカウント
- Laravelがインストールされている状態
- Kinstaのアプリケーションホスティングを使用するためのMyKinstaアカウント(お持ちでない場合は、無料利用枠をお使いください)
XAMPPのコントロールパネルで、ApacheとMySQLモジュールサービスが稼働していることを確認します。実行されていない場合は、「Actions」欄の各サービスの「Start」ボタンをクリックしてください。XAMPPのコントロールパネルは以下のようになっています。
デフォルトでは、MySQL/MariaDBはポート3306で動作します。ポートを変更する場合は注意してください。
XAMPP以外のウェブサーバーを使用している場合は、Apacheまたは他のサーバーソフトウェアを実行し、ローカルマシンにMariaDBサーバーをインストールします。
phpMyAdminのクイックスタート
- MySQLとApacheが起動している状態で、ブラウザにアクセスします。
- phpMyAdminを開き、
http://localhost/phpmyadmin/
を貼り付けると、以下のような画面が表示されます。
phpMyAdminは、MySQLとMariaDB用のデータベース管理ツールです。
Laravelプロジェクトの作成
これで、Laravelを使ってブログを作成する準備が整いました。オペレーティングシステムはWindowsを使用します。
- マシンのターミナルかコマンドラインインターフェイス(CLI)にアクセス。
laravel new blog
コマンドで、Laravelプロジェクト「blog」を作成します。cd blog
コマンドで、プロジェクトのblogディレクトリを開きます。- このディレクトリをコードエディターで開きます。
- プロジェクトが正常にビルドされたことを確認するため、ターミナルまたはCMDで
php artisan serve
を実行。 - ローカルのアドレス出力をクリックし、ブラウザに出力。ブラウザに、デフォルトのLaravelウェルカムページが表示されればOKです。
データベースの設定
次にブラウザでphpMyAdminに戻り、データベース「blog」を作成し、設定を行っていきます。
- 「Database」タブで「Create database」セクションのフィールドに「blog」と入力します。
- 「Create」ボタンをクリック。
- blogプロジェクトのルートにある.envファイルのデータベース接続を更新。
DB_DATABASE
とDB_PASSWORD
の値を作成したものに置き換えます。
接続情報は、以下のようになります。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog
DB_USERNAME=your-db-username
DB_PASSWORD=your-db-password
その他のデータベース接続情報は.envファイルと同じになりますが、DB_PORT
を3306から3307に変更するなど、接続の値を変更した場合は、.envファイルを更新してください。
投稿テーブルの作成
続いてデータベースモデルを作成し、変更を移行します。
- ターミナルで
php artisan make:model Post -mc
を実行し、モデル「Post」、テーブル「posts」、マイグレーションファイル、コントローラーを作成します。
- database/migrationsディレクトリを確認し、作成したマイグレーションファイルを開きます。ファイルの形式は、
YYYY_MM_DD_ID_create_posts_table.php
です。 - マイグレーションファイルの
up()
メソッドにtitle
、description
、image
属性を持つスキーマを作成。
public function up() {
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->text('description')->nullable();
$table->string('image')->nullable();
$table->timestamps();
});
}
- ターミナルに移動し、
php artisan migrate
を使用して、以下のように変更を移行します。
- ブラウザでphpMyAdminにアクセスし、postsテーブルを確認します。
コントローラーの作成
ビューとコントローラを追加すると、データベースセットのビジネスロジックが実装されます。ビューは、モデルからのデータオブジェクトを表示するユーザーインターフェース。コントローラーは、モデルとビュー間のデータ実行の流れを管理する役割を担います。
- Bladeファイルを作成する前に、ターミナルでまず
npm install
、その後npm run dev
を実行します。最初のコマンドは、必要なnpmパッケージをインストールするもので、2つ目のコマンドでVite開発サーバーを起動します。 - app/Http/Controllersディレクトリに移動し、PostController.phpファイルを開き、コントローラーメソッドの
index
を作成します。このメソッドは、単純なテキストをブラウザにレンダリングするもの。PostController
クラスに以下のコードを貼り付けます。
public function index() {
$post = "Laravel解説記事パート1";
return view('posts.index', ['post'=>$post]);
}
これによって、$post
をコンテキスト変数として、インデックスBladeテンプレートのviews
セクションに渡します。$post
は表示するテキストで(この例では「Laravel解説記事パート1」)、後ほどこれを投稿のループに置き換えます。
- resources/viewsディレクトリに、layoutsとpostsの2つのディレクトリを作成します。
- layoutsディレクトリ内にapp.blade.phpファイルを作成します。他のBladeファイルはこのファイルを継承。
- 以下のコードをapp.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>Blog</title>
<!-- Styles →
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<!-- Navbar →
<header>
<nav class="navbar bg-primary">
<div class="container-fluid">
<a class="navbar-brand" href="{{ route('posts.index') }}">Mini-Blog</a>
</div>
</nav>
</header>
<body>
@yield('content')
</body>
<footer class="footer mt-auto py-3 bg-dark">
<div class="container d-lg-flex justify-content-between">
<span class="text-light">Mini-Blog © 2023</span>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</html>
このHTMLコードを使用することで、Bootstrapバージョン 5.2.3、JavaScript、CSSアセットをバンドルするViteをインポートします。生成されたページには、ナビゲーションバー(navbar)付きのヘッダーと、その下にスクリプトが呼び出されたフッターがあります。本文は、@yield('content')
によって、他のBladeファイルから動的コンテンツがレンダリングされます。
postsディレクトリには、createとreadオペレーションを実装するためのBladeファイルが格納されています。
- postsディレクトリ内にBladeファイル「index.blade.php」を作成し、以下のコードを貼り付けます。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="titlebar">
<h1>Blog list</h1>
</div>
<hr>
<p>The Blog 1 - {{ $post }}</p>
</div>
@endsection
このコードは、layoutsページのapp.blade.phpファイルから継承しています。ブラウザでレンダリングすると、各ブログ記事のコンテンツと、layoutsフォルダ内のapp.blade.phpファイルから継承したナビゲーションバーとフッターが表示されます。セクションタグの間に、アプリケーションの実行時にブラウザでレンダリングするコンテンツを、コントローラーから渡します。
- routesディレクトリにルートを設定。ルートを設定することで、App/Providersディレクトリの
RouteServiceProvider
(アプリのルートファイルの読み込みを担うクラス)を自動的に読み込むことができます。 - routes/web.phpファイル内で
use AppHttpControllersPostController
を使って、PostControllerをインポートします。 Route::resource('posts', PostController::class);
をroutes/web.phpファイルに追加し、ルートを設定。- Vite開発サーバーを起動したまま、
php artisan serve
を使ってターミナルでアプリケーションを実行。 - ブラウザで
http://127.0.0.1:8000/posts
を開き、ブログ記事リストを表示します。
ページは以下のようになるはず。
次のステップは、すべての投稿の表示、投稿の作成、そして投稿を保存するためのコントローラーメソッドの定義です。対応するセクションでルートを追加し、Bladeファイルを作成します。
ブログ投稿ページの作成
タイトルを入力し、説明を追加したら、画像をアップロードしてブログ記事を作成します。それから、記事を順番に表示しましょう。
- app/ModelsディレクトリでPost.phpファイルを開きます。
use HasFactory;
コードブロック下のPost
クラスに、protected $fillable = ['title', 'description', 'image'];
を追加。
このコードによって、大量割り当てからモデルの属性を保護します。
- app/Http/Controllers/PostController.phpファイルで、
use AppModelsPost;
を使用してPost
モデルをインポート。 PostController
クラスのindex
とcreate
コントローラーメソッドを以下のコードに置き換えます。
// すべての投稿を表示
public function index() {
$posts = Post::orderBy('created_at', 'desc')->get();
return view('posts.index', ['posts' => $posts]);
}
// 投稿を作成
public function create() {
return view('posts.create');
}
先ほど作成したindex
メソッドによって、PHPアプリケーションがすべての投稿を取得し、時系列に並べた上で、posts
変数に格納します。return viewで、views/postsディレクトリのコンテキスト変数として、投稿がindex.blade.phpファイルに渡されます。create
メソッドはcreate.blade.phpファイルを返し、投稿を作成しようとすると、views/postsディレクトリに配置します。
- 以下のコードを使用して、コントローラメソッドの
store
を作成(ブログ記事をデータベースに保存)。次のコードをindex
とcreate
メソッド下のPostController
クラスに貼り付けます。
// 投稿を保存
public function store(Request $request) {
// 検証
$request->validate([
'title' => 'required',
'description' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$post = new Post;
$file_name = time() . '.' . request()->image->getClientOriginalExtension();
request()->image->move(public_path('images'), $file_name);
$post->title = $request->title;
$post->description = $request->description;
$post->image = $file_name;
$post->save();
return redirect()->route('posts.index')->with('success', 'Post created successfully.');
}
store
メソッドは、本文のデータに関するクライアントのリクエストを処理し、引数としてrequest
を受け取ります。次に、投稿を作成する際に使用されるフィールドを検証し、Post
モデルからpost
インスタンスを作成します。入力されたフィールドデータは、作成されたインスタンスに割り当てられ、保存されます。「Post created successfully」(投稿が作成されました)というフラッシュテキストとともに、index
のビューにリダイレクトされます。
投稿へのルートの追加
以下の手順で、web.phpファイルにルートを追加します。
- プロジェクトのルートにあるroutesディレクトリで、web.phpファイルを開きます。
- 既存のコードを次のように置き換えて、コントローラーメソッドのルートを登録。
<?php
use IlluminateSupportFacadesRoute;
use AppHttpControllersPostController;
Route::resource('/', PostController::class)->names([
'index' => 'posts.index',
'create' => 'posts.create',
'store' => 'posts.store',
'show' => 'posts.show',
]);
これらのルートによって、データオブジェクトが作成、保存、表示されます。
Bladeファイルの作成
ビューを作成するには、PostController
クラスに戻ります。
- resources/views/postsディレクトリに、Bladeファイル「create.blade.php」を作成し、以下のコードを貼り付けます。
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Add Post</h1>
<section class="mt-3">
<form method="post" action="{{ route('posts.store') }}" enctype="multipart/form-data">
@csrf
<!-- データ未入力時のエラーメッセージ -->
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="card p-3">
<label for="floatingInput">Title</label>
<input class="form-control" type="text" name="title">
<label for="floatingTextArea">Description</label>
<textarea class="form-control" name="description" id="floatingTextarea" cols="30" rows="10"></textarea>
<label for="formFile" class="form-label">Add Image</label>
<img src="" alt="" class="img-blog">
<input class="form-control" type="file" name="image">
</div>
<button class="btn btn-secondary m-3">Save</button>
</form>
</section>
</div>
@endsection
上記では、まずcreate.blade.phpが@extends('layouts.app')
を使用して、layoutsディレクトリのapp.blade.phpのコンテンツ(ヘッダー、ナビゲーションバー、フッターなど)を継承します。また、h1
タグ内にAdd Post
テキストを追加して、{{route('posts.store')}}
アクションを含むpost
メソッドでフォームを作成します。
enctype="multipart/form-data"
は、画像のアップロードを可能にするもので、csrf
はクロスサイトスクリプティング(XSS)攻撃からフォームを保護するものです。そして、エラーメッセージによって無効なフィールドエントリと属性(field attributes
)が表示され、フォームのラベルと入力項目が生成されます。
- index.blade.phpファイルのコードを以下のコードに置き換えて、すべてのブログ記事を表示します。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="titlebar">
<a class="btn btn-secondary float-end mt-3" href="{{ route('posts.create') }}" role="button">Add Post</a>
<h1>Mini post list</h1>
</div>
<hr>
@if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif
@if (count($posts) > 0)
@foreach ($posts as $post)
<div class="row">
<div class="col-12">
<div class="row">
<div class="col-2">
<img class="img-fluid" style="max-width:50%;" src="{{ asset('images/'.$post->image)}}" alt="">
</div>
<div class="col-10">
<h4>{{$post->title}}</h4>
</div>
</div>
<p>{{$post->description}}</p>
<hr>
</div>
</div>
@endforeach
@else
<p>No Posts found</p>
@endif
</div>
@endsection
このコードによって、投稿追加ボタンが実装されます。クリックすると、投稿が作成され、任意のデータがページの本文に渡されます。if
の条件は、データベースにデータがあるかどうかをチェックします。データがある場合はパス、データがなければ、「No Posts found」(ページが見つかりませんでした)と表示されます。
ページの構造化
これで、php artisan serve
を使用して、ブログ記事を作成・表示するアプリケーションを実行できます。<a href="http://127.0.0.1:8000">http://127.0.0.1:8000</a >
を開くと、ページは次のようになるはず。
記事を追加すると、このように表示されます。
LaravelブログをKinstaにデプロイする方法
Kinstaのアプリケーションホスティングサービスを利用して、Laravelアプリをデプロイおよびテストするには、以下の手順に従ってください。
- .htaccessファイルの作成
- コードをリポジトリにプッシュ
- MyKinstaでデータベースを作成
- MyKinstaでプロジェクトをセットアップ
- ブログをビルドしてデプロイ
.htaccessファイルの作成
プロジェクトのルートフォルダに.htaccessファイルを作成し、以下のコードを貼り付けます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
これによって、アプリケーションのリクエストをデプロイメント内のpublic/index.phpにリダイレクトします。
コードをリポジトリにプッシュ
プロジェクトのリポジトリを作成して、コードを公開します。GitHub、GitLab、またはBitbucketを使用してコードをホストし、MyKinstaにデプロイできます。
MyKinstaでデータベースをセットアップ
以下の手順で、MyKinstaにデータベースを作成します。
- 「サービスを追加」ボタンをクリックして、「データベース」を選択。
- データベースの情報を入力(以下スクリーンショット参照)。なお、「データベースのユーザー名」はデフォルトのままにしてください。
設定する情報は、データベース名、表示名、データベースタイプ、 バージョン、データベースのユーザー名、データセンターの所在地、およびサイズです。今回の例では、データベースにMariaDBを使用し、サイズは「Db3(CPU=1/RAM=4GB/ディスク容量=10GB)82.55ドル/月)」を選択します。データベースのタイプとサイズは、要件に応じて選択してください。
- 設定を終えたら、「続行」をクリック。
- 月額料金を確認し、支払い情報を選択して、「データベースを作成」をクリックします。
MyKinstaでプロジェクトをセットアップ
続いて、アプリケーションをMyKinstaにデプロイします。
- MyKinstaの「ダッシュボード」画面に移動します。
- 「サービスを追加」をクリックし、「アプリケーション」を選択。
「アプリケーションの追加」画面で以下の設定を行います。
- 「ブランチの選択」セクションでGitHubリポジトリを選択し、「コミットに際し自動でデプロイ」にチェックを入れます。
- 「基本情報」セクションでアプリケーション名を入力し、データセンターの所在地を選択。
- Laravelはデプロイ時にアプリキーが必要になるため、「環境変数」セクションを開いて、「キー1」に「APP_KEY」を追加します。ローカルの.envファイルで定義されたAPP_KEYを使用するか、Laravelキージェネレーターを使って取得可能です。
- 「続行」をクリックして次に進みます。
- アプリケーションのビルドリソース(CPUとRAM)を選択します。この例では、「標準のビルドマシン(1CPU/4GB RAM)」を使用。
- 「コンテナイメージを自動で設定」は選択したまま次の項目へ。
- 「続行」をクリック。
- 「プロセスのセットアップ」で、アプリケーションのポッドサイズとインスタンスを変更可能です。今回の例ではデフォルト値を使用。
- 「続行」をクリック。
- 最終確認画面で利用料金や支払い方法を確認し、「アプリケーションを作成」をクリックして、アプリケーションのデプロイを開始します。「デプロイメントの詳細」画面にリダイレクトされ、デプロイメントの進行状況が表示されます。
ブログをビルドしてデプロイ
続いて、データベースとアプリケーションをホストした状態で、データベースをアプリケーションに接続し、ビルドしてデプロイします。
データベースを接続するには、外部接続を使用します。データベースの「情報」画面の「外部情報」セクションで必要な情報を確認できます。
- デプロイしたアプリの「設定」画面の「環境変数」セクションに移動します。
- 「環境変数を追加」をクリックし、外部接続に必要な情報を設定します。.envファイルと同じ変数を使用してください。
手動で編集した<code>env</code>変数を他の変数と区別したい場合には、上記スクリーンショットを参考にしてみてください。
「APP_URL」はホストしているアプリケーションのURLで、「DB_CONNECTION」はmysql
です。
- アプリケーションの「設定」画面を開きます。
- 「Buildpack」セクションでPHPとNode.jsをBuildpackとして追加します。PHPアプリケーションであるため、PHPのBuildpackは最後に追加してください。
- 「デプロイする」をクリックしてアプリケーションを再構築します。
次に、データベースマイグレーションのプロセスを追加します。
- 「アプリケーション」>「プロセス」画面に移動します。
- 「ランタイムプロセス」セクションの「プロセスを追加」をクリック。
- 名前に「Migration」、タイプに「バックグラウンドプロセス」、startコマンドに
php artisan migrate --force
をそれぞれ設定します(Podサイズとインスタンスはデフォルト値のままでOK)。 - 「続行」をクリックしてプロセスを作成。これによってビルドがトリガーされ、アプリケーションが再デプロイされます。
- アプリケーションの「ドメイン」画面でアプリケーションのリンクをクリック。
- なお、MyKinstaにデプロイされたブログアプリケーションには、投稿が表示されません。タイトルを入力し、説明を追加したら、画像を選択して投稿を作成します。
まとめ
Laravelを使えば、シンプルなブログをすぐに開発することができます。高速なページ読み込み、堅牢なコントローラーアーキテクチャ、堅牢なセキュリティにより、アプリケーションのパフォーマンスも容易に向上可能です。Kinstaの専用コントロールパネル「MyKinsta」を使えば、ウェブアプリケーションを効率的にリリース、出荷できます。また使用した分だけ支払う従量制の価格設定により、隠れたコストもありません。
Kinstaのホスティングなら、LaravelアプリがGoogle Cloud Platformのプレミアムティアで実行されるため、最高速度を実現できます。さらに、Cloudflare統合によるエンタープライズレベルのDDoS対策、悪意のあるユーザーを寄せ付けない高度なファイアウォールなども付帯します。
ウェブアプリ開発とホスティングをレベルアップしませんか?まずはアプリケーションホスティングの無料利用枠でその性能をお試しください。
コメントを残す