Laravelとか初めて使うよ!出たばっかりなので試す。
この記事はLaravel5.0が出たばかりに書いた内容です。最新の内容と必ず比較してください。
インストール
PHP5.5以上とmcrypt/openssl/mbstringとcomposerが入ってる前提。 まずインストーラのインストール
php composer.phar global require "laravel/installer=~1.1"
プロジェクトの作成
laravel new blog
とりあえず
$ php artisan -v Laravel Framework version 5.0 Usage: [options] command [arguments] Options: --help (-h) Display this help message --quiet (-q) Do not output any message --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug --version (-V) Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output --no-interaction (-n) Do not ask any interactive question --env The environment the command should run under. Available commands: clear-compiled Remove the compiled class file down Put the application into maintenance mode env Display the current framework environment help Displays help for a command inspire Display an inspiring quote list Lists commands migrate Run the database migrations optimize Optimize the framework for better performance serve Serve the application on the PHP development server tinker Interact with your application up Bring the application out of maintenance mode app app:name Set the application namespace auth auth:clear-resets Flush expired password reset tokens cache cache:clear Flush the application cache cache:table Create a migration for the cache database table config config:cache Create a cache file for faster configuration loading config:clear Remove the configuration cache file db db:seed Seed the database with records event event:generate Generate the missing events and handlers based on registration handler handler:command Create a new command handler class handler:event Create a new event handler class key key:generate Set the application key make make:command Create a new command class make:console Create a new Artisan command make:controller Create a new resource controller class make:event Create a new event class make:middleware Create a new middleware class make:migration Create a new migration file make:model Create a new Eloquent model class make:provider Create a new service provider class make:request Create a new form request class migrate migrate:install Create the migration repository migrate:refresh Reset and re-run all migrations migrate:reset Rollback all database migrations migrate:rollback Rollback the last database migration migrate:status Show a list of migrations up/down queue queue:failed List all of the failed queue jobs queue:failed-table Create a migration for the failed queue jobs database table queue:flush Flush all of the failed queue jobs queue:forget Delete a failed queue job queue:listen Listen to a given queue queue:restart Restart queue worker daemons after their current job queue:retry Retry a failed queue job queue:subscribe Subscribe a URL to an Iron.io push queue queue:table Create a migration for the queue jobs database table queue:work Process the next job on a queue route route:cache Create a route cache file for faster route registration route:clear Remove the route cache file route:list List all registered routes schedule schedule:run Run the scheduled commands session session:table Create a migration for the session database table vendor vendor:publish Publish any publishable assets from vendor packages
とか出ればOK。コマンド眺めるだけでも充実してるのがわかる。
artisan
はアルチザンと読むらしい。ちなみにlaravelはララベル。
ついでにサーバも立ち上げてみる。
$ php artisan serve
Laravel development server started on http://localhost:8000
昔はphp artisan serve
とかあったらしいけど何故か消えたらしい。まあ別にphpコマンドで十分だから必要ないのかもしれない。
アプリ名の設定
php artisan app:name MyBlog
app以下のnamespaceが変わるだけっぽい。
ただしこのままだとcomposerの設定が残ってて動かないので、php composer.phar update
を一発叩く必要がある。
その他の設定
環境によってはstorageに書き込み権限が必要。
面倒だったらHomestead
というVagrant boxを使うと初期設定を全部スキップできる。
ルーティング
app/Http/routes.php
が最初に読まれるファイルになる。
ここに処理を直接書くこともできる。マイクロフレームワークっぽい。
// app/Http/routes.php Route::get('/hello', function() { return 'Hello World'; });
これでhttp://localhost:8000/hello
にアクセスするとHello World
と表示される。
ルーティング(コントローラー)
まあ正直これだとだるいので、コントローラーにも書ける。どっちも選べるのは良い。 routes.phpを見た時点で気がついているだろうけど、ルーティングに文字列を入れるとコントローラー指定になる。
// app/Http/routes.php Route::get('/', 'WelcomeController@index');
でもこれでも個別で指定するの面倒なので
// app/Http/routes.php Route::controller('article', 'ArticleController');
とかでコントローラーまとめて指定できる。
この場合、URLとメソッドの対応をどのようにすればいいのかと言うと、[リクエストメソッドの小文字][URLパラメータの頭大文字]
という指定でできる。つまり/article/index
は、public function getIndex()
となる。このへんリフレクションでやってるっぽいので、ちょっと遅いかもしれない。Route::get()
のような指定方法のほうが高速に見える。コントローラー使わないのが不便だけど最速っぽい。
ちなみにいわゆるsnake_case
→CamelCase
変換ではなく、url-pattern
→Function_name
という変換が入る。ちょっと変な感じ。function getShow_user()
みたいな変なメソッド名になる。
Controllerの書き方は他のやつをコピペするか、この後のCRUD自動生成で生成でも良い。
laravel-annotationsを入れるとアノテーションでも書ける。
CRUD自動生成
昔懐かしのscaffoldみたいなやつ。
php artisan make:controller ArticleController
で、routes.phpに
// app/Http/routes.php Route::resource('article', 'ArticleController');
とすると、indexとかstoreとかshowとかってメソッドにすぐアクセスできるようになる。 昔懐かしのscaffoldと違うのは、中身は用意してくれないので、自分で書く必要がある。まあ管理画面作るくらいなら便利なんじゃないのって感じ。余計なお世話はしてくれない。
ビュー(テンプレート)
ビューはresources/views/
に入れる。なんでControllerと同階層じゃなくてトップレベルなの?という疑問が残るが、それがいいと思ったのだろう。
テンプレートエンジンはBladeと呼ばれるLaravel用エンジンが使われる。{{ $hoge }}
で変数を出力して、条件式などは@から始まる書式を使う。拡張子は.blade.php
。末尾phpである必要あるのかな?
// app/Http/Controllers/ArticleController.php class ArticleController extends Controller { public function getIndex() { return view('article.index', ['hoge’=>’<fuga>']); }
とか作って
<!— resources/views/article/index.blade.php —> @extends('app') @section('content') article index {{ $hoge }} @endsection
で表示ができる。
ちなみに昔は{{ }}
はエスケープせずに表示で、エスケープする場合は{{{ }}}
だったらしいが、5からはどちらもエスケープするようになり、エスケープしない場合は{!! !!}
という書式を使う必要がある。
モデル
モデルはデフォルトでapp/
直下に置くらしい。うーん。
とりあえずここではそのままapp/
直下に置くが、autoloadされるディレクトリであればどこでもいいらしいので、必要であれば変えれば良い。
app/Article.php
を作る。
<?php namespace MyBlog; // app/Article.php use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $table = 'articles'; }
スキーマはここには書かず、database/migrations/
に書く。このファイルはartisan
コマンドで生成する。
$ php artisan make:migration --table=articles create_articles
Created Migration: 2015_02_05_120749_create_articles
中身を書く
// database/migrations/[日付とか]_create_articles.php /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function(Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('body'); $table->dateTime('created_at'); $table->timestamp('updated_at'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('articles'); }
流す前にDBの設定をしておく。config/database.php
で設定する…と思いきや、ルートにある.env
ファイルを書き換えれば大抵は大丈夫なようになっている。.env.example
をコピーして.env
ファイルを作り、DB_xxxを変更する。なおMySQLがデフォルト。
変更したらデータベースは事前に作っておいて、以下のコマンドを流す。
$ php artisan migrate:install
Migration table created successfully.
$ php artisan migrate:refresh
Nothing to rollback.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2015_02_05_120749_create_articles
こんな感じ。
とりあえずインタラクティブシェルで試す。
$ php artisan tinker Psy Shell v0.3.3 (PHP 5.6.4 — cli) by Justin Hileman >>> $articles = \MyBlog\Article::all(); => <Illuminate\Database\Eloquent\Collection #00000000104d1a7300000001133ee921> {} >>> $article = new \MyBlog\Article(); => <MyBlog\Article #00000000104d1a7200000001133ee921> { incrementing: true, timestamps: true, exists: false, snakeAttributes: true, manyMethods: [ "belongsToMany", "morphToMany", "morphedByMany" ] } >>> $article->title = 'test'; => "test" >>> $article->body = 'test test'; => "test test" >>> $article->save(); => true >>> $articles = \MyBlog\Article::all(); => <Illuminate\Database\Eloquent\Collection #00000000104d1a7000000001133ee921> {} >>> $articles = \MyBlog\Article::all()[0]; => <MyBlog\Article #00000000104d1a7800000001133ee921> { incrementing: true, timestamps: true, exists: true, snakeAttributes: true, manyMethods: [ "belongsToMany", "morphToMany", "morphedByMany" ] } >>> $articles = \MyBlog\Article::all()[0]->title; => "test" >>> $articles = \MyBlog\Article::all()[0]->body; => "test test" >>> \MyBlog\Article::all()[0]->delete(); => true >>>
画面に出してみる。
// app/Http/Controllers/ArticleController.php /** * Display a listing of the resource. * * @return Response */ public function getIndex() { $articles = \MyBlog\Article::all(); return view('article.index', ['articles'=>$articles]); } /** * Show the form for creating a new resource. * * @return Response */ public function getCreate() { $article = new \MyBlog\Article(); $article->title = 'test'; $article->body = 'test test'; $article->save(); return redirect('article/index'); }
<!— resources/views/article/index.blade.php —> @extends('app') @section('content') @foreach ($articles as $article) <section> <h3>{{ $article->title }}</h3> <p>{{ $article->body }}</p> </section> @endforeach @endsection
これで/article/create
を叩くと、延々とデータが増えるのを観察することができる。