Laravel
準備
セットアップ手順
- Composer をインストール
C:/Users/Shota/AppData/Roaming/Composer/vendor/bin
にパスを通すcomposer global require "laravel/installer"
基本
laravel new ${myProjectName}
php artisan serve # テスト専用コマンドである。本番環境では使うな。
本番環境のセットアップ(XAMPP の例)
例えばhtdocs
にmy-app
というプロジェクトを放り込んだとすると、https://some.com/my-app/public
というアドレスでアプリケーションにアクセスできる。
/my-app/public
を/
にマップしたい(エイリアスを作りたい)場合は、本書 P20 に記載の設定を Apache の httpd.conf
に入れること。
ファイル・フォルダ構成
ルートファイル
name | description |
---|---|
.env , .env.example | DB の認証情報など、動作に関する設定ファイル |
artisan | php artisan *** のようにして使う |
composer.json , composer.lock | composer がつかう |
phpunit.xml | ユニットテストに関する設定ファイル |
server.php | サーバ本体 |
webpack.min.js | webpack の設定ファイル |
ルートフォルダ
*
マークはよく使うフォルダ。
name | description |
---|---|
app | * アプリケーションの本体 |
bootstrap | 起動時の処理 |
config | 設定 |
database | * DB 関係 |
public | そのまま公開するファイル群。パスを取得したいときはasset() ヘルパを使う |
resources | * テンプレートや、ビルドすべき JS/CSS などのリソース |
routes | * ルーティング情報 |
storage | ログなどのファイルの保存場所 |
tests | ユニットテスト関係 |
vendor | Laravel 本体のプログラム |
app フォルダ
name | description |
---|---|
Console | コンソールプログラム? |
Exceptions | 例外処理 |
Http | Web アプリケーションにアクセスしたときの処理。一番良く使う |
Providers | サービスプロバイダ アプリ開始時の処理などを記述する |
User.php | ユーザ認証に関するプログラム |
routes フォルダ
name | description |
---|---|
api.php | API の機能を特定のアドレスに割り当てたい時に使う |
channels.php | ブロードキャストチャンネルのためのルーティング? |
console.php | コンソールプログラムのためのルーティング? |
web.php | 一般的な Web ページとしてアクセスするときのルーティング。一番良く使う |
ルーティングとコントローラ
ルーティング
ルーティングの設定はroutes/web.php
に記載する。
生の HTML を返す
Route::get('/hello', function() {
return '<h1>Some HTML!</h1>';
});
// GET以外のメソッドの場合
Route::post();
Route::put();
Route::delete();
テンプレートを指定する
(実際はview()
は Response オブジェクトを返す)
// routes/web.php
Route::get('/', function() {
return view('welcome');
}); // => `resources/views/welcome.blade.php`
Route::get('/hello', function() {
return view('hello.index');
}); // => `resources/views/hello/index.blade.php`
コントローラを指定する
Route::get('/hello', 'HelloController@index');
Route::get('/hello', 'HelloController'); // シングルアクションコントローラの場合
params を受け取る
任意の param には?
をつける。任意の項目にはデフォルト値をセットしておくと良い。
Route::get('/hello/{msg}/{id}', function($msg, $id){ // 順に渡されるので名前は違ってもOK
return "<h1>Hello! $msg2 $id</h1>";
});
Route::get('/hello/{msg?}/{id?}', function($msg='a', $id='b'){
return "<h1>Hello! $msg $id</h1>";
});
ルートの一覧を表示する
php artisan route:list
コントローラ
MVC
User <-> Controller <-┬-> View <-> Templates
│
└-> Model <-> Database
コントローラの作成
# 空のコントローラを作成する
php artisan make:controller HelloController
# リソースフル(典型的なメソッドをあらかじめ持っている)なコントローラを作成する
php artisan make:controller HelloController --resource
// app/Http/Controllers/HelloController.php
namespace App\Http\Controllers; // 名前空間の指定
use Illuminate\Http\Request; // Requestオブジェクトを使えるよう設定
class HelloController extends Controller {}; // コントローラ本体
アクションの追加
- アクション=コントローラに用意される処理のこと
- 名前を変えることで、複数設定できる
- インスタンスメソッドとして実装する
- アクションは、HTML もしくはリクエストオブジェクトを Return する
// controller
class HelloController extends Controller
{
public function index() {
return <<<EOF
<h1>ID: $id</h1>
<h1>Pass: $pass</h1>
EOF;
}
}
コントローラをルーティング設定に記載する。
// routes/web.php
Route::get('/hello', 'HelloController@index');
シングルアクションコントローラ
一つしかアクションを持たないクラスの場合、__invoke()
メソッドを実装することで記載を簡略化できる。
// controller
class HelloController extends Controller
{
public function __invoke() {
return '<h1>something</h1>';
}
}
ルーティング設定ではメソッド名を省略する。
// routes/web.php
Route::get('/hello', 'HelloController');
リソースフル
- Resourceful = RESTful に加え、追加・編集・削除用フォーム等、リソースを扱うために必要なすべての機能を備えていること
- 下記の手順でリソースフルなコントローラを作成し、作成したコントローラを
Route::resource
に渡してやることで、アクションを個別に作成することなく、簡単にリソースフルなコントローラを使い始めることができる。
php artisan make:controller RestappController --resource
Route::resource('/rest', 'RestappController');
http method | route | action | RESTful | Resourceful |
---|---|---|---|---|
GET | /route | index() | * | * |
GET | /route/create | create() | * | |
POST | /route | store() | * | * |
GET | /route/1 | show() | * | * |
GET | /route/1/edit | edit() | * | |
PUT/PATCH | /route/1 | update() | * | * |
DELETE | /route/1 | destroy() | * | * |
フォームから PUT や DELETE を送るには
- リソースフルなルートを設定した場合は、更新や削除の処理を
PUT
やDELETE
といったメソッドで行う必要がある。 - しかし、フォームから遅れるのは
POST
メソッドだけである。 - このため、
PUT
やDELETE
を使う際は、_method
という隠し属性にメソッドを記述しておく必要がある。
<form action="/posts/1234/delete" method="POST">
<input type="hidden" name="_method" value="PUT" />
</form>
アクションで params を受け取る
// routes/web.php
Route::get('/hello/{id?}/{pass?}', 'HelloController@index');
// controller
class HelloController extends Controller
{
public function index($id='defualtId', $pass='defaultPass') { /* do something */}
}
Request, Response の利用
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class HelloController extends Controller
{
public function index(Request $request, Response $response) {
$html = <<<EOF
<h1>Request</h1>
<pre>$request</pre>
<h1>Response</h1>
<pre>$response</pre>
EOF;
$response->setContent($html);
return $response;
}
}
主なメソッド
$request->url()
クエリを含まない URL を返す$request->fullUrl()
クエリを含む URL を返す$request->path()
ドメインより下のパス部分だけを返す$request->QUERY_NAME
クエリを取得する(クエリ名が id なら、$request->id
)$response->status()
ステータスコードを返す$response->content()
コンテンツを取得$response->setContent()
コンテンツを設定
なお、Laravel では、下記のデータが全てリクエストオブジェクトにぶっこまれる(Express のように、req.params や req.query などはなく、いきなり req.propertyName の形で追加される)。
- params
- query string
- form data (input の name 属性)
- ミドルウェアから渡された値(
$request->merge(配列)
など)
ビューとテンプレート
PHP テンプレートの利用
PHP テンプレートを使うには、view(フォルダ名.ファイル名)
を呼ぶことで、テンプレートから Response インスタンスを作成する。
Route::get('/hello', function(){
// resources/views/hello/index.phpというテンプレートを基にする
// view()はResponseインスタンスを生成する
return view('hello.index');
});
上記は、ルーティング設定にテンプレートを指定している。 ルーティング設定にコントローラを指定した場合は、次にようにする。
class HelloController extends Controller
{
public function index() {
return view('hello.index');
}
}
テンプレートにデータを渡したいときは、view の第二引数に Array を渡す。
// controller
class HelloController extends Controller
{
public function index() {
// compact等を使って、渡すデータを一つづつ指定する方法
$title = 'my title';
$msg = 'my msg';
return view('hello.index', compact('title', 'msg'));
// 配列を使って、まるごとデータを渡す方法
$data = [
'msg1' => 'msg1です',
'msg2' => 'msg2です',
];
return view('hello.index2', $data);
}
}
// template
<h1>{{ $title . $msg }}</h1>
<h1>{{ $msg1 . $msg2 }}</h1>