【PHP】Laravel で WEBアプリケーション開発
以前に仕事で、Laravelを使ったWEBアプリケーションの開発に携わりました。本記事はその際の忘備録になります。
macOSにLaravelをインストールして開発環境を整える
macOSバージョン
$ sw_vers
ProductName: macOS
ProductVersion: 14.2
BuildVersion: 23C64
PHPバージョン
$ php -v
PHP 8.3.2 (cli) (built: Jan 16 2024 13:46:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.2, Copyright (c) Zend Technologies
with Zend OPcache v8.3.2, Copyright (c), by Zend Technologies
Composerのインストール
brew install composer
バージョン
composer --version
Composer version 2.6.6 2023-12-08 18:32:26
Laravelインストーラーのグローバルインストール
composer global require laravel/installer
環境パスを通す
laravelコマンドを使うために以下の通り追加:
export PATH="$PATH:/Users/mopipico/.composer/vendor/bin"
新しいターミナルセッションで動作確認:
laravel -v
Laravel Installer 5.2.0
Usage:
command [options] [arguments]
Options:
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
completion Dump the shell completion script
help Display help for a command
list List commands
new Create a new Laravel application
これでLaravelコマンドが使えるようになった。
Laravelプロジェクトの作成
適当なディレクトリへ移動し、新規プロジェクトを作成する:
laravel new test_laravel
質問を適宜選択
プロンプトが表示されるので、適宜選択する。

今回選択した回答:
- Would you like to install a starter kit?: No starter kit
- Which testing framework do you prefer?: PHPUnit
- Would you like to initialize a Git repository?: No
- Which database will your application use?: MySQL
プロジェクトディレクトリへ移動
cd test_laravel
作成されたプロジェクトルート下で、Laravelのバージョンを確認する:
php artisan --version
Laravel Framework 10.43.0
プロジェクトサイトへアクセスする
ローカルサーバーの起動
Laravel開発サーバーを起動するには、プロジェクトルート下で次を実行:
php artisan serve
Webブラウザで http://localhost:8000/
へアクセスし、下図のようにサイトが表示されればLaravel開発環境構築の成功。

プロジェクトを編集して、Hello world を表示してみる
routes/web.php
ファイルを開き、以下のように編集:
Route::get('/', function () {
return 'Hello World';
});
これで、ブラウザを開いて http://localhost:8000 にアクセスすると、“Hello World” と表示される。

Laravelに登録されているコマンドリスト(バッチ用)を一覧表示する
Laravelでは php artisan list
を使うと、php artisan
で実行できるコマンドの一覧が表示されます。その中から、Command
クラスを継承して作った独自コマンドだけを一覧表示する場合は、次のようにフィルタすると良いです(macOS、linux環境)。
php artisan list | grep 'command:'
実行すると $signature
に登録されたcommand:
から始まるコマンドだけを一覧表示できます。
command:batch-task1 Command description
command:batch-task2 Command description
command:batch-task3 Command description
LaravelでTailwind CSSが反映されない
Laravelでレイアウト調整するために、bladeにTailwindのクラスを追加したのですが、反映されませんでした。結論から言うと
npm run dev
を起動してなかったのが原因でした。php artisan serve
と npm run dev
は、Laravelアプリケーションの異なる側面を処理するために使用されるコマンドであり、それぞれのルートディレクトリやURLの違いについて説明します。
php artisan serve
- 目的: Laravelの内蔵開発サーバーを起動するために使用します。
- ルートディレクトリ: Laravelプロジェクトのルートディレクトリ(通常はプロジェクトのルートフォルダ)。
- URL: デフォルトでは
http://127.0.0.1:8000
でアクセスできます。 - 機能:
PHPで書かれたバックエンドコード(ルーティング、コントローラー、モデルなど)を処理します。静的ファイル(CSS、JavaScript)は
public
フォルダから提供されます。
php artisan serve
npm run dev
- 目的: フロントエンドアセットのビルドおよび開発サーバーの起動を行うために使用します。
- ルートディレクトリ: 一般的には
webpack.mix.js
に設定されたルートディレクトリ。開発用のファイルをpublic
フォルダに出力します。 - URL: 通常、Webpackのデフォルト設定では
http://localhost:8080
などのURLでアクセスします。これは設定によって変わる場合があります。 - 機能: JavaScriptやCSSなどのフロントエンドアセットのホットリロードやビルドを行います。Webpack Dev Serverを使用して、変更が即座に反映される開発環境を提供します。
npm run dev
組み合わせて使用する方法
このスクリプトは、MySQLサーバー、フロントエンドの開発サーバー(npm run dev)、およびLaravelのサーバーを起動し、Control + Cで終了すると各サーバーを停止します。
#!/bin/bash
# MySQLサーバーを開始
mysql.server start
# 作業ディレクトリを移動
cd web/
# npm開発サーバーをバックグラウンドで起動
npm run dev &
NPM_PID=$!
# Laravelサーバーを特定のポートでバックグラウンドで起動
php artisan serve --port=8700 &
LARAVEL_PID=$!
# Ctrl+Cが押されたらサーバーを停止するためのトラップを設定
trap "echo 'Stopping servers...'; kill $NPM_PID $LARAVEL_PID; mysql.server stop; exit" INT
# サーバーのプロセスが終了するまで待機
wait $NPM_PID
wait $LARAVEL_PID
Laravel で実行されたSQLをログに表示したい
Laravelは、ORM機能によってSQLを直接書かずにデータベース操作を行えてコーディングがとても楽です。しかし、デバッグ作業で実行されたSQLを実際に見たい場合も多々あります。そういった場合に、logファイルに実行されたSQL文を出力する二つの方法をご紹介いたします。
enableQueryLog() を使った方法
こちらは最も手軽なSQLのプリントデバッグ方法です。
public function index()
{
// SQLログを有効にする
DB::enableQueryLog();
$perPage = config('constants.pagination.per_page');
$persons = Person::where('delete_flg', 0)->paginate($perPage);
// 実行されたSQLを取得
$queries = DB::getQueryLog();
Log::info($queries);
return view('persons.index', compact('persons'));
}
tail -f ./storage/logs/laravel.log
を実行すれば、次のような形で出力されるはずです。
[2024-07-23 20:07:59] development.INFO: array (
0 =>
array (
'query' => 'select count(*) as aggregate from `a_m_person` where `delete_flg` = ? and `user_id` = ?',
'bindings' =>
array (
0 => 0,
1 => 7,
),
'time' => 0.61,
),
1 =>
array (
'query' => 'select * from `a_m_person` where `delete_flg` = ? and `user_id` = ? limit 2 offset 2',
'bindings' =>
array (
0 => 0,
1 => 7,
),
'time' => 0.72,
),
)
しかしながら、毎回囲うのは手間ですし、管理もしずらくなります。
DB::enableQueryLog();
...
$queries = DB::getQueryLog();
Log::info($queries);
そこで次に紹介する方は、ミドルウェアを使って、ルーターレベルで一括管理できる方法を紹介いたします。
ミドルウェアの作成
まず、ミドルウェアを作成します。
php artisan make:middleware LogSqlQueries
生成されたミドルウェアファイルに以下のコードを追加します。
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class LogSqlQueries
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// SQLログを有効にする
DB::enableQueryLog();
$response = $next($request);
// 実行されたSQLを取得
$queries = DB::getQueryLog();
Log::info('SQL Queries:', $queries);
return $response;
}
}
ミドルウェアをルートに適用
次に、ミドルウェアを適用したいルートにミドルウェアを登録します。routes/web.php
やroutes/api.php
にて、以下のようにミドルウェアを適用します。
use App\Http\Middleware\LogSqlQueries;
Route::middleware([LogSqlQueries::class])->group(function () {
Route::get('/persons', [PersonController::class, 'index']);
// 他のルート
});
twig の使い方
twig(ツイッグ)は、PHPで人気の、テンプレートエンジン。
Symfony(2007年)を開発した、Sensio labs社が2009年に開発。
何も考えずに開発すると、PHPとHTMLでスパゲッティ状態になるところ、twigを使うことで、PHPとHTMLを分離することができる。 つまり、ロジックとUIの分離ができ、メンテナンス性や開発速度の向上を図れる。
開発環境
macOS環境にて以下の通り、composerとphpがインストール済み。
$ composer --version
Composer version 2.6.6 2023-12-08 18:32:26
$ php --version
PHP 8.3.2 (cli) (built: Jan 16 2024 13:46:41) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.2, Copyright (c) Zend Technologies
with Zend OPcache v8.3.2, Copyright (c), by Zend Technologies
ComposerはPHPの依存関係管理ツール
プロジェクトに必要なライブラリやパッケージを管理し、インストールや更新を容易に行える。
Twigを使って”Hello, World!“をブラウザに表示するまで
まずは使って twig
の感触と便利さを体験する。
適当な場所に空のプロジェクトディレクトリを作成。そこのルートへ移動して、以下のコマンドを実行:
composer require twig/twig
これで twig
がPHPで使えるようになった。
必要なディレクトリを作成
ファイルを管理しやすいように、プロジェクト配下に
templates
と compilation_cache
ディレクトリを作成:
mkdir templates compilation_cache
テンプレートファイルを作成
templates
ディレクトリ内に hello.html.twig
という名前のテンプレートファイルを以下内容で作成:
<html>
<body>
<p>Hello, {{ name }}!</p>
</body>
</html>
Twigの環境を設定
index.php
を作成し、というファイルにTwigの基本設定を記述した例です。
<?php
require_once './vendor/autoload.php';
$loader = new \Twig\Loader\FilesystemLoader('./templates');
$twig = new \Twig\Environment($loader, [
'cache' => './compilation_cache',
'auto_reload' => true,
]);
Twigがテンプレートをコンパイルした後のキャッシュを
./compilation_cache
へ格納される。キャッシュ機能を使用しない場合は、このオプションを省略する。
Twigテンプレートをレンダリング
最後に、index.php
にTwigテンプレートをレンダリングするコードを追加:
// ... 前のTwig設定コード ...
echo $twig->render('hello.html.twig', ['name' => 'World']);
結果をブラウザに表示
phpコマンドで、ローカルサーバーを起動:
php -S localhost:8000
http://localhost:8000/index.php
へアクセスして「Hello,
World!」が表示されれば成功。
Composer を使った Guzzle HTTP
PHPのCompoerへの理解を深めるために、ライブラリをインストールしてプログラミングしてみます。今回はGuzzle HTTPクライアント
をインストールして、HTTPリクエストしてみました。
開発環境
ソフトウェア | バージョン |
---|---|
macOS | 14.2 |
php | 8.3.2 |
composer | 2.6.6 |
guzzlehttp/guzzle とは
guzzlehttp/guzzle
とは、Comoser でインストール可能な PHP
の HTTP client library
です。公式ページによれば、次のようにしてHTTPリクエストを行うことが可能になります。
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
echo $response->getStatusCode(); // 200
echo $response->getHeaderLine('content-type'); // 'application/json; charset=utf8'
echo $response->getBody(); // '{"id": 1420053, "name": "guzzle", ...}'
// Send an asynchronous request.
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
$promise = $client->sendAsync($request)->then(function ($response) {
echo 'I completed! ' . $response->getBody();
});
$promise->wait();
guzzlehttp/guzzle のインストール
適当なワーキングディレクトリを作成して、そこへ移動してから
composer require guzzlehttp/guzzle
を実行します。
$ composer require guzzlehttp/guzzle
./composer.json has been created
Running composer update guzzlehttp/guzzle
Loading composer repositories with package information
Updating dependencies
Lock file operations: 8 installs, 0 updates, 0 removals
- Locking guzzlehttp/guzzle (7.8.1)
- Locking guzzlehttp/promises (2.0.2)
- Locking guzzlehttp/psr7 (2.6.2)
- Locking psr/http-client (1.0.3)
- Locking psr/http-factory (1.0.2)
- Locking psr/http-message (2.0)
- Locking ralouphie/getallheaders (3.0.3)
- Locking symfony/deprecation-contracts (v3.4.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 8 installs, 0 updates, 0 removals
- Installing symfony/deprecation-contracts (v3.4.0): Extracting archive
- Installing psr/http-message (2.0): Extracting archive
- Installing psr/http-client (1.0.3): Extracting archive
- Installing ralouphie/getallheaders (3.0.3): Extracting archive
- Installing psr/http-factory (1.0.2): Extracting archive
- Installing guzzlehttp/psr7 (2.6.2): Extracting archive
- Installing guzzlehttp/promises (2.0.2): Extracting archive
- Installing guzzlehttp/guzzle (7.8.1): Extracting archive
2 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
4 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
Using version ^7.8 for guzzlehttp/guzzle
実行結果の通り、guzzlehttp/guzzle
に依存するライブラリも同時にインストールされていることがわかります。
インストール後のディレクトリ
composerを使ってライブラリをインストールすると、composer.json
やcomposer.lock
といったファイルが生成されます。そしてvendor
ディテクトりに、ライブラリが格納されます。
$ tree -L 2 9:02:57
.
├── composer.json
├── composer.lock
└── vendor
├── autoload.php
├── composer
├── guzzlehttp
├── psr
├── ralouphie
└── symfony
composer.json
生成された composer.json
パッケージのバージョンがキャレット演算子で指定されています。これは、次のメジャーバージョンまでのすべての変更を利用可能にするものです。下記の場合
>=7.8 <8.0
に相当します。
{
"require": {
"guzzlehttp/guzzle": "^7.8"
}
}
Guzzle HTTPクライアントを使ったリクエスト
それでは実際にPHPでGuzzle HTTPクライアントを使ったテストを行います。
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
echo $response->getStatusCode();
echo $response->getHeaderLine('content-type');
echo $response->getBody();
このようにGuzzle
HTTPクライアントを使うことで、HTTPリクエストをわかりやすく記述することができます。
require 'vendor/autoload.php';
はオートローダーという仕組みで、インストールしたパッケージから外部ファイルやクラスなどを自動で読み込んでくれ流ため、いちいち必要なクラスを取り込むために
include
や require
で記述せずに済みます。
use GuzzleHttp\Client;
で名前空間を指定して、クラスやメソッドを使いやすくします。
今度は、PSR-7リクエストを使って非同期でHTTPリクエストを実行してみます。
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
$client = new Client();
$request = new Request('GET', 'http://apppppp.com/jojo.json');
$promise = $client->sendAsync($request)->then(function ($response) {
// 非同期で実行される
echo '②I completed! ' . $response->getBody();
});
echo "①先に処理する\n";
$promise->wait();
echo "③待ってから処理する\n";
sendAsync
で非同期でHTTPリクエストを投げ、レスポンスが完了したところでthen
メソッド内のクロージャ(無名関数)が実行されます。よって、echo "①先に処理する\n";
が先に実行されます。その後の記述
$promise->wait();
では、非同期リクエストが完了するまで待機します。ですから、クロージャが実行された後に、echo "③待ってから処理する\n";
が実行されるわけです。
このプログラムを実行すると、次のような結果となるはずです。
$ php main.php
①先に処理する
②I completed! {
"name":"Jyotaro",
"stand":"The World"
}
③待ってから処理する