Laravel ざっくり調べた
Laravel、急いで勉強する必要ができたので、概要まとめます。あくまでざっくり調べたまとめなので、コード書いたときに誤認に気がつくんだろうなと思います。
phpもしっかり勉強したことがないので、php 7 のインストールや基本的な文法からやり直します。Laravel に関しても完全に手探りなので、フレームワークの基本的な使い方やデファクトなパッケージについて調べます。
Laravel はバージョンごとにかなり差異があるという話を聞きます。なのでバージョンに関しては慎重に選ぶべきだとは思うのですが( LTS などを選択した方が合理的だと思うのですが )、大枠をつかめればいいかなと思っているので、せっかくだし現在最新の Laravel 5.6 についてここでは書きたいと思います。
php
php は対応しているサーバーにおけば動くスクリプト言語で、リクエストとかセッションとか変数にアクセスできて便利だなーくらいの認識です。言語の概要ってどう書けばいいのかわかりません。
とりあえず小さなコードを書きつつ、「インストール」、「基本的な文法」、「デバッグ」、を学びまず軽度な修正をできるようにし、「ファイルの取り扱い」、「外部パッケージの取り扱い」を学んで機能の追加ができるようになればいいなと思います。
インストール
php 7.1 以上をインストールしたいと思いましたが、私の環境では macOS を High Sierra にバージョンアップしたからなのか、すでに php 7.1 が入っていました。それ以前の macOS を使っている場合は php -v
でバージョンを確認の上 7 以下が入っていたら、Homebrew などでインストールするといいかもです。
$ brew install php $ vim ~/.bashrc # 以下を追記 export PATH="$(brew --prefix php)/bin:$PATH" $ source ~/.bashrc
基本的な文法
ここの抜粋です。自分が見直しやすいようにメモしておきます。
index.php ファイルを作って、以下を書き込みます。
<?php echo 'hello';
php + ファイル名でコードの実行ができます。
$ php index.php hello
このファイルを編集しながら文法練習していきます。行末のセミコロンは必須みたいです。また、 php -a
で対話環境の起動ができるみたいです。
- 変数: 基本的に
$変数名 = 値
で宣言。型は色々ある。文字列、数値は他の言語とだいたい同じで困らなそう。- 論理型:
TRUE
とかTrue
とかtrue
とかありで不安。FALSEは同値な値がたくさんある。論理型を取り扱う際は注意する。 - 配列: リテラルで書けるので基本的に気にしなくていいが、オブジェクトではない(?)ので
length
とか無い。配列操作に関しては色々関数があってややこしそう。 - 辞書:
$dic = [ 'h' => 'hoge', 'f' => 'fuga'];
のようにアロー=>
でキー・バリューの組みを記述していく。要素の追加は$dic['p'] = 'piuo';
という想像通りの感じ。 $_REQUEST
,$_POST
などのスーパーグローバル変数は、そんなものがそういえばあるという感じで、存在を覚えておく。
- 論理型:
- 定数: ローカル定数がない!?グローバル定数は
define(名前, 値)
かconst 名前 = 値
で。const
はトップレベルスコープなので関数内でイミュータブルな値が欲しいのならdefine
を使おうかと思ったが、関数外からアクセスできるようになってしまうので気持ちが悪い。なので再代入に関しては 定数に頼らず読みやすいコードを書く という当たり前の結論。多分使い方的には環境変数的なもの。 - 関数:
function 関数名(変数型 $変数名1, 変数型 $変数名2...): 戻り値型
で宣言。型情報かけるようになった(書かなくても動くは動く)。return
で戻り値を返す。変数のスコープは基本的に関数内で閉じている。デフォルト引数、可変長引数ありだけど順番に気をつける。参照渡しもあるけど今はあまり気にしない。- 可変関数:
function hoge() { … }
があれば"hoge"()
が実行できるらしい。リフレクションみたい、便利だと思う。 - クロージャ: 無名関数。
function () { ... }
。親のスコープから値を引き継ぐには専用の構文がいるので、安心感ある。
- 可変関数:
- 演算子: 参照代入
$a = &$b
は読むとき気をつける。比較演算は等号も不等号も=
の数が増えるほど厳密(型チェックが入るかどうか)と覚える。バッククォートでくくると実行演算子と呼ばれシェルコマンドの実行ができるらしいが、覚えておかなくて良さそう?どうなんだろう?加算子/減算子は使える。 文字列結合は.
、配列結合は+
。 - 制御構文:
if
について気にすべきところはelse if
、elseif
共に可ということ。ブラケットではなくコロンを使った記法も可能でその場合はelseif
のみ。コロンの時はendif
を書く。while
、for
、foreach
、switch
もコロンによる記法に関して同様だが、switch
はブロック<?php ... ?>
を分割した時にcase
のインデントでエラーが出ることがある。また、switch
は==
での比較を行う。break
は制御構文の終了、continue
はその回のループを終了。declare
はディレクティブの宣言で、タイプヒントの厳密型チェックとか有効にできる。- ファイル読み込みに関して、
require
はinclude
と違ってエラーを投げる。_once
つけると読み済みのファイルは読み込まない。
- ファイル読み込みに関して、
- class:
class ClassName { ... }
で定義。__construct
でコンストラクタ。 プロパティ、メソッド共にアクセス制御修飾子(public
,protected
,private
)をサポートしているし、省略はできない(var
では書けるけどその意味はあまりなさそう)。new ClassName()
でインスタンス化。フィールドへのアクセスは->
。static
で静的なメソッドを宣言でき、アクセスはClassName::メソッド名
のように書く。静的なプロパティはconst
で定義できる。 クラス内での静的フィールドはself
から、非静的フィールドはthis
からアクセス。クラスパスを解決させることができる、オートロードという仕組みもあるらしい。繼承はextends
でできるのは単一繼承。メソッドのオーバーライド可能、parent::メソッド名
で呼び出し。抽象メソッドabstruct
、インターフェースinterface
もある。トレイトは静的、非静的メソッドもプロパティも持てる、宣言はtraitトレイト名
で、使用する際はuse トレイト名
。無名クラスも使える。オーバーロード が他の言語と異なる意味で使われているので注意。オブジェクトはフィールドに対して反復処理foreach ($obj as $k => $v)
が書ける。 - 名前空間:
namespace 名前空間名
で宣言。 - 例外:
try
,catch
,finnaly
で対応。catch (ExceptionA | ExceptionB e)
のように複数例外をキャッチできる。
デバッグ
ちょっとまだわかっていないです。var_dump
引数の中身を見せてくれます。配列とかはエコーしても Array
だけなので必要だと思います。詳細度は落ちますが print_r
もなかなかいいみたいです。
$arr = [ 'hoge', 'fuga', [ 'hoge', 'fuga' ] ];
という配列に対してそれぞれの関数を適応して見ます。
print_r
Array ( [0] => hoge [1] => fuga [2] => Array ( [0] => hoge [1] => fuga ) )
var_dump
array(3) { [0]=> string(4) "hoge" [1]=> string(4) "fuga" [2]=> array(2) { [0]=> string(4) "hoge" [1]=> string(4) "fuga" } }
print_r
の方が人間的には読みやすそうですね。(読みやすさが大切かどうかは時と場合によりますが)
ファイルの取り扱い
php でコードを書くときは、とりあえず <?php
とファイルの先頭に書き、拡張子を .php
にすれば良さそうです。 <?php
の閉じタグに関しては書くと予期せぬ挙動が起こることがあるため省略するのが流儀のようです。
ファイルの読み込みは include
, include_once
, require
, require_once
で行うことができます。 dirname(__FILE__)
がスクリプトファイルのディレクトリを参照してくれているため、つなげて相対パスで require_once(dirname(__FILE__).'/hoge/fuga/piyo.php')
のように書くことができるようです。現在位置を明示しないまま ../hoge
などのパスを書いた場合、そのファイル自体が別の場所から読み込まれた際にパスがずれてしまうためしっかり書いたほうが良さそうです。
これらの理解も若干微妙ですが、それはさておき php のパッケージ管理システム Composer
を使うとオートロードと呼ばれる、ファイルの自動読み込み機能を使うことができるみたいです。
外部パッケージの取り扱い
パッケージの依存性管理ツールに関して。ちょっと前に触ったときは pear
を使ったような気がしたのですが、近年は Composer
が主流なのでしょうか?確かに上で書いたオートロードなどの機能が魅力的です。パッケージの検索は、https://packagist.org を利用すると良さそうです。
インストールについては Laravel の説明の箇所に書きます。設定ファイルもcomposer.json
だし、composer init
でパッケージを作成できるみたいで、結構 npm
っぽい気がします。パッケージの追加は composer require
です、—dev
フラグもあり、開発環境のみ依存しているパッケージを管理することができます。
Laravel
ここでは「インストール」、「フレームワークの構成」、「ツール」、「テスト」、「デファクトなパッケージ」を学んで Laravel でプログラミング始める基礎知識がわかればいいなと思います。
インストール
今のところバージョン 5.6 が最新のようなのでそれをインストールします。日本語版ドキュメントを参照しつつインストールをして行きます。 (若干英語版と日本語版のサイトのトップページが違ったり?)
Composer
Laravel はライブラリ管理ツール Composer を使って入れるようです。とりあえず Composer 入っていなかったのでインストールします。
こちらを参考にインストールします。Laravel のドキュメントではグローバルインストールが推奨のようです。
一応 Homebrew (brew install homebrew/php/composer
) でもいけました。(が php の依存性がなくなったため必要なら自分で入れてくださいというメッセージが表示されました、という解釈であっている?)。最近の mac は php 入っていると思うので気にしないで大丈夫そうです。(問題あったら是非教えてください)
Laravel インストーラ
$ composer global require "laravel/installer"
laravel コマンドを使用できるように、 .bashrc などにパス追記して、再読み込みします。
$ vim ~/.bashrc # 以下の内容を追記 export PATH=$HOME/.composer/vendor/bin:$PATH $ source ~/.bashrc $ laravel -v Laravel Installer 2.0.1
無事 Laravel コマンドが入りました。
laravel new apps_name
アプリの雛形を作成してみます。何にするか迷いますが、とりあえず、ユーザーがいてログインとか何かしらの投稿とかがあって、という感じがいいかなと思います。
$ laravel new i_bought_it
結構重いですね、このコマンド、Rails の rails new
的な。
中身は以下の感じでした。
$ tree -L 1 . ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── server.php ├── storage ├── tests ├── vendor ├── webpack.mix.js └── yarn.lock 10 directories, 8 files
Node.js 関連のファイルが入っているんですね。この辺りは「フレームワークの構成」あたりで調べて行きます。
ローカルで起動
とりあえず起動してみます。
$ cd i_bought_it $ php artisan serve
localhost:8000 でサーバーが立ち上がりました!
開発環境
2019/01/22 追記 Laradock が楽で良いです。
結論としてはビルトインサーバーと、 sqlite で頑張ることにします。
$ touch database/database.sqlite $ vim .env # 以下の内容に変更 DB_CONNECTION=sqlite DB_DATABASE=database/database.sqlite
以下ざっとみた感じです。
Homestead: 開発環境としては、サーバーとかデータベースとか全部入りの Homestead という選択肢もあるそうです。 ただ Homestead は Vagrant と VirtualBox (またはその他仮想化ツール) が必要らしいので、若干面倒くさい気分になりました。
Valet: Valet というのも開発環境として選択肢に入るようです。 データベース は別途管理する必要がありますが、 ssl の動作確認も起動オプションだけだし、 Homebrew だけで完結するのが素敵です。ただし Mac オンリーなので Windows での開発に加わる場合ちょっとまごつく可能性もありそうです。
Docker: ノリノリで環境構築してたけど Composer から何から全部 docker でいけたんじゃないかということに気がつきました。例えば: Dockerでlaravelの開発環境構築をしてみた (php-pfm,nginx, mysql)
フレームワークの構成
Laravel の構成について整理してみます。
基本的には「サービスコンテナ #」を中心に考えて行けば良さそうです。サービスコンテナに対して様々なサービスを、「サービスプロバイダ #」によって組み立て、登録していきます。これによってアプリケーションの機能を柔軟に変更、管理していく感じのようです。
「ファサード #」はサービスコンテナに登録されているサービスへの API を提供するようです。API の直接の使用のほかにも、「コントラクト #」を使用することでコンストラクタやアクションでタイプヒントを指定しておけばサービスコンテナによって DI される仕組みがあるようです。(コントラクトの登録方法がわかってないですが、、、また、自分の理解ではサービスプロバイダで登録したサービスもタイプヒントによって DI されるのかなと思います)
ORM としては 「Eloquent ORM」 が Laravel に含まれているようですが、使用必須というわけでもないようです。クエリビルダーのようなものであるという話です。ローカルスコープなども定義できるようなので、リポジトリーなどの抽象化がいるかどうかは少し悩みます。論理削除(ソフトデリート)を提供しているようで、論理削除自体の賛否は置いておくとして、実際家な思想に好感が持てます。
ルーティングは Route サービスを(ファサードを通して)使って登録していきます。ルートの登録時、またはコントローラーのコンストラクタで、ミドルウェアを適応することができます。ミドルウェアによってコントローラのアクションに対して認証などの機能を追加することもできるようです。ミドルウェアの登録に関しては App/Http/Kernel.php で記載されています。
(ルーティングに関してリフレクションを使っているのか、URI セグメントから自動的にクエリしてくれる「暗黙の結合 # 」のあたりで、変数名とURIセグメントの一致を要求している部分が面白いです。変数名が意味を持っているのは、気がつかないでハマりそう。)
コントローラーは通常のクラスか、 App/Http/Controllers/Controller.php を継承したクラスです。クラスが依存するサービスは、コントローラーのコンストラクタにおいて引数をタイプヒントで与えておけば、サービスコンテナの仕組みが解決してくれるようです。アクションに対しても同様に DI してくれるようです。(Request などが顕著)
フロントエンドに関しては、 Blade テンプレートエンジン、CSS (SASS、LESS)、Vue が Laravel 5.6 の標準のようです。NPM のエコシステムに乗って webpack によって各種コンパイルを行います。テンプレートの描画は view ヘルパーによってコントローラーから行います。
ツール
artisan が開発において基本的なツールになりそうです。必要そうなものとしては、以下のものかなと思います。
- artisan list: コマンド一覧
- artisan route: ルーティング関連、特に route:list
- artisan make: コードの自動生成系
- artisan tinker: 対話環境
パッケージに関しては composer を使ってインストールしていくのが無難そうです。 フロントに関しては yarn かと思います。
テスト
テストフレームワークとしては phpunit が初めから入っていました。標準的な Unit, Feature の他に Browser テストが行えるようで (Laravel Dusk)、 Selenium のインストールなしにブラウザ自動操作とテストができるようです。保守の場合は重宝しそうです。
ものすごく個人の感想ですが、とりあえず Unit テストは必須で書いていく、Feature はベストエフォートで、Browser は要件次第かなと思いました。
デファクトなパッケージ
色々探そうと思っていたのですが、 Laravel って標準で色々な機能が入っているようです。認証とかページネーションとか。パッケージ自体は github にたくさん上がっているようです。どこで探すのが正解かわかってないですが、ググると以下のサイトで検索できそうです。
- https://packagist.org/: Composer のパッケージリスト
- https://packalyst.com/: Laravel のパッケージリスト
- https://www.larablocks.com/: Laravel のパッケージリスト
感想
印象としてはフレームワークとしての自由度が、構造を容易に変えられるという意味で、めちゃくちゃ高いなと思いました。でも頑張ればしっかり管理できそうな感じです。バージョン間での差異が少し気になるところですが、逆にそれも自由度が高いが故の変更なのかと思います。どちらかといえばフレームワークの使い方を学ぶよりは、サービスコンテナ自体をしっかりコードを追うなり勉強しておけば、バージョン間の差異についていけるような気がします。