カテゴリー別アーカイブ: Laravel

LaravelのMiddlewareについて

アプリケーションを試しに作っているのだが、過去の「結局Laravelに戻って、ぼちぼち始める」で認証の仕組みが簡単に組み込めるよ、てなことを書いて、確かに認証ができていた。しかし、この認証は、未ログイン時に自分を登録するとアカウントが自動的に作成される、ということを想定したものだった。

そこで、ログインした際にのみ登録画面を表示させようと、app/Http/route.phpに以下のように書いてみたのだった。

すると、確かにログインする前に「/register」で登録画面を出そうとすると、ログイン画面にリダイレクトされる。よしよし。と思っていたが、書き足した「’middleware’ => ‘auth’」というのの意味がわからず、「これを書けば認証が必要になるんだな」の程度しか思ってなかった。

さてさて、ユーザー登録に認証が必要になったので良かった。と思って、今度は認証後に登録させようと、ログイン後のプルダウンメニューに登録を追加するため、resources/views/layouts/app.blade.phpに以下のように書き換えた。

そしていざ、ログイン後に登録画面を表示しようとすると、あれ、トップ画面にリダイレクトされちゃう。あれれ、と思って探していたら、これがミドルウェアという仕組みでそうなっているのであった。ミドルウェアとはコントローラーにアクセスする前や後に必ず実施するフィルタみたいなものらしい。

app/Http/Middlewareを見たところ、「RedirectIfAuthenticated.php」というそのもののリストがあり、リダイレクトしているのはここであることがわかった。じゃあどこでこれを呼び出すように定義されているのか、というと、app/Kernel.phpのrouteMiddlewareというマップで定義しているらしい。同じファイルにmiddlewareというのもがあるが、これは必ず実施するミドルウェアで、middlewareGroupsはミドルウェアをグループ分けできるものらしい。routeMiddlewareで定義されたキーと値のペアは、値はミドルウェアの実装クラスで、キーをどう使うか、というところで、route.phpのさっきの

の「’middleware’ => ‘auth’」の’auth’だったのだ。なーるほど。

で、登録時に「RedirectIfAuthenticated」ミドルウェアを通るときにリダイレクトされてしまっていたので、これは’guest’というキーにしたがって動いていることがわかった。んで、今度はコントローラー「app\Http\Controllers\Auth\AuthController.php」を見てみたところ、コンストラクタにそれらしきものがあった。

‘except’って「除く」ってことらしいから、logoutはログイン中の’guest’ミドルウェアからは除きますよ、って定義をしてあるようだ。だからログイン中にログアウトできるということだから、ここを

ってやってみたら(ここはメソッド名を書くようです)、想定通りログイン画面でユーザー登録フォームが出てきた!やった!

で、このミドルウェアって、artisanコマンドで

で、「Middleware」でどのミドルウェアを経由するかを見られるようで、routeMiddlewareに定義されたマップのキーがここに書かれている。「auth」が未認証時に認証画面に飛ばされるミドルウェア、「guest」が認証時にルート画面に飛ばされるミドルウェアであるようで、

のようになっていればOKだと思う。

Laravelのフォームのチェックボックス

前回、モデルについてモデルの属性はどこにかくのだ、とか書いていたが、いろいろやっている間に、フォームでチェックボックスを実現するときどうするのだろう、ということになったのでその覚え。

フォームをLaravelCollectiveというモジュールを使って実現する、っていうのをララ帳などで確認して作業していたが、私の案件では、チェックボックスをたくさんつけて、複数選択をさせる、という必要があった。ララ帳では触れていなかった(ような)ので、最初は、以下のように書いていた。

DBのほうは、booleanで指定するのもいいけど、項目数の変動が想定されるので、そのたびにマイグレーションしたくないな、と思って、選択肢を各ビットと見立て、DBには1つのカラムにOR演算した結果(合計値)を数値として入れておく、ビットでフラグを表現してカラムを1つにすることを想定した。

当初、コントローラークラスで、都度各ラベルの合算をして、とやっていたのだが、どうも腑に落ちない。なんかミューテータとか使えそうじゃないの?と思っていたけど選択肢の名前とDBに書き込む名前が違うので、そのままでは使えなさそう。

まいっか、と他の部分をいろいろ実装していたが、解決のきっかけとなったのは以外にもバリデーションだった。バリデーションをやろうとしたとき、「どれか1つ以上を選択してください」というやつをこの書き方では簡単には実現できないことに気づき、いろいろ調べることとなる。

チェックボックスや、ラジオボタンなどのグループ化をどうやってるんだろう、とかいろいろ探していたら、以下のように書いて配列で実現できるとの情報を見つけた。

こうすると、choiceという配列1つでチェックボックスの選択肢が表現できる。そして1つ以上のチェックをつけてねというバリデーションチェックは、以下のように簡単に実現できるようになった(FormRequestという機能で、Requestクラスの拡張クラスを使っています)。

また、こうすると、複数のチェックボックスが1つの変数で表現できるので、ああミューテーターが使える!

こんな感じで実現できた!途中いろいろはしょっている、とにかくララ帳がすばらしいのでララ帳でわかんなかったところのみをメモとして残している。

LaravelのMVCのモデル

前回、データベースの1対多について悩んだことをメモ書きしておいたが、ただ、そもそもMVCのモデルをどう定義すりゃいいのよ、ということを全く考えていなかった。

Javaのクラス的な考え方で、make:modelで作った時に作られる、appディレクトリ直下に作られるモデル名のPHPファイルで、クラス変数として定義しなきゃなんないんだろうな、と思い込んでいて、それらしい記事を探すけどどこにもない。モデルの要素をどこに定義すればいいのよ、と探していたが、実際は少なくともクラス変数として定義する必要はなかった。

モデルを作った時に、make:modelで作った時に「-m」オプションをつけると、database/migrationsディレクトリにマイグレーション用のファイルができる。どうやらここに定義したテーブル名が、そのままモデルの要素と考えていいような印象を受けた。

ではappディレクトリ直下に置かれるモデル名のPHPファイルは何をするのか、というので、前回はDBのテーブル名の定義などをやってたが、何かDBとPHPの変数の間をコンバートする必要があるときに、それを定義できる「ミューテータ」という機能があることがわかった。たとえupdate_atなどの日付のデータはテキストになってしまいますが、これをPHPのCarbonというDateTimeを扱うクラスのインスタンスに変更してくれる、など。

あとは、マスアサインメントといって、登録できるカラム名を定義しておき、それを配列で渡すことでレコードを操作できるような仕組みがあって、それの定義をここでやるみたいです。

ここらへんの知識の大半は、「ララ帳」というすごくわかりやすいホームページが参考になっている。対象バージョンが5.1ではあるのだが、最初から進め方がきちんと押さえられているので、とても理解がし易い。昨年7月から更新が止まっているので残念なんですが、とても助かっている。

でも、私がJavaから先に入っているので、どうしてもモデル名のphpファイルに定義されたモデル名のクラスに、クラス変数を定義しなきゃいけないんじゃないの?と思ってしまうのって、誰もわかってくれないか・・・

LaravelのEloquentで悩む

前回から、モデルを定義して、モデルと密接に関係しているデータベースとの関わり合いをうまいところやってくれるらしいEloquent ORMというものをいろいろ探って試行錯誤してみていたけど、よくわかっていない。とりあえずやったことを書き残す。

前回、troubleというモデルをartisanコマンドでひな形を作ったところで終わった。で、私の設計上、このtroubleというモデルは、自らに対して1対nの関連性を持つような想定だ。親のtroubleに、複数のtroubleがぶらさがる、ツリー構造のようなイメージだ。

で、troubleがもつカラムとしては、長文のテキスト「document」の1つのみとした。

まずは前回atrisanコマンドで作ってもらったマイグレーション用のファイルdatabase/migrations/~create_troubles.php をいろいろなドキュメントを見よう見まねで修正した。因みにupメソッドが作成するとき、downメソッドが元に戻すときのことを書くらしい。

この5行目でdocumentカラムの定義だが、6行目では、自分の親のidを納めるtrouble_idカラムを定義している。そして、9行目で、外部キー束縛を定義している。これでマイグレーションをし直す。

> php artisan migrate:refresh

すると、MySQLのデータベースを見ると、テーブルに「document」と「trouble_id」のカラムが追加されている。よしよし。

そして、今度は、App\Trouble.phpを以下のように修正した。

ここでテーブル間の相関関係を定義するらしい。便宜上ツリーに見立てて1を親、nを子として説明するが、hasManyが、子クラス(App\Trouble)と親のApp\Trouble間には、子のtrouble_idに親のidをもつ形で複数の関係あるよ、ということになって、belongsToは、その逆、子から1つの親があるよ、ということになるらしい。

さらに、Seederっていって、データベースの初期状態を定義できる仕組みを使って、操作方法を確かめてみる。databases\seeda\DatabaseSeeder.phpを以下のように修正した。

で、artisanにてseedを実行!

> php artisan db:seed

そしてt_troubleテーブルを見ると、「ぶらさがります」と「こっちもぶらさがり」のtrouble_idに、「こんにちは世界」のidが入っているのがわかる。うまくいっているようですねー。

親を先にsaveでDBに格納しておかないと、親のIDがわからないので、当然うまくいかないようだ。そしてtrb1のtroublesで関連づけたくてtrb2を書き込むときは、「$trb1->troubles()->save($trb2)」って書くところがなかなか思いつかないのねー。

この状態で、

とやると、idが1のレコードにぶら下がるレコード群をdata変数へ得ることができるようです。

今日はここまで…

結局Laravelに戻って、ぼちぼち始める。

PHPixieでいろいろやってたけど、私の読解力不足で、なんともならなかったので、結局Laravelに戻ってきた。Laravelに戻ってきた理由はいろいろあるけど、英語が苦手な私も日本語ドキュメントや日本人によるユーザー事例(ブログなど)が充実していたことが一番大きい。でも、最新版を使うのなら、結局英語のドキュメントを参照せざるを得なくなるのだけれど。

不安もある。これはフレームワーク全般に関する不安だろうが、マイナーバージョンアップでも結構な変更点がありそうなところだ。でもセキュリティサポートのパッチが同一バージョンで2年?3年リリースされるようなので、とりあえず大丈夫だろう。

フレームワークを使おうとした一番の理由は、セキュリティの問題だ。もちろん開発者が考慮していなければならないのは変わらないが、フルスクラッチで組むよりは遙かに考慮点が少なくなる(のではないかという希望を与えてくれる)ということだ。また、ユーザー認証の仕組みなども、フレームワークで考慮されていれば、とりあえず導入するのもフルスクラッチに比べれば手間はかからない(のではないかという希望を与えてくれる)ということもある。

ということで、ぼちぼち作り始める。手順はLaravelのサイトにあるDocumentの中にあるチュートリアルの、「Basic Task List」をやっていきながら、同じような目的のことをやっていくことにした。

とりあえず「Laravelの続き。quickstart-basic-masterをやってみる。」でやったように、プロジェクトの作成およびhttp.confでAliasの設定、そして.htaccessファイルの修正を行った。

そのまえに、ユーザー認証の機構を使うので、ユーザー認証の仕組みはあらかじめ追加しておいた。

> php artisan make:auth

これだけで認証の仕組みができるんだから、フレームワークはありがたいね。

最初に、モデルを作成してみる。モデルは、Eloquentという仕組みを使うらしい。解説ページを見ながら、とりあえずやってみた。

> php artisan make:model -m Trouble

これでいいのかな?結果、app直下に各クラス定義のphpファイルが、database/migrationsにマイグレーション用と思われるファイルが生成されていた。

最初にDBのテーブル名を定義する。クラス変数「$table」に定義しておくと大丈夫らしい。たとえば

のように。

今日はここまで・・・

Laravelの続き。quickstart-basic-masterをやってみる。

あれからちょっと間が開いたが、公式のドキュメントを読んで、チュートリアル的な物をやってみようと思った。

コマンドプロンプトで「php artisan」とやってみて、ヘルプを表示させたら、頭に「Laravel Framework version 5.2.20」と表示されて、Laravel 5.2だということを知った。私が見ていたドキュメントは日本語版の5.1までのやつだったので、どうせなら新しいのを見てやろうということで、5.2のドキュメントを見始めた。そこでチュートリアル的なものを探していたら、「クイックスタート」があったのでやってみることに。どうやらタスクを追加したり削除したりするだけの単純なアプリケーションらしい。

指示に従い、GitHibからソースをダウンロードし、xamppのApacheのhtdocsにフォルダ(laravel)を作ってコピーした。その後、以下のようにしてLaravelのコンポーネントをインストールする。

> cd laravel
> composer install

そして、XAMPPのMySQLで、PHPMyAdminからデータベースを新規作成し、「.env」ファイルでデータベースの設定を上書きしたあと、マイグレーションを実施してみた。

> php artisan migrate

とりあえずテーブルができたようで、実行してみた。ルートに前回見つけた「.htaccess」を置いてみたところ、とりあえず最初の画面の表示がされたが、タスクを追加しようとするとエラーに…

どうやらリダイレクトがうまくいっていないようで、リダイレクトの無限ループを起こしているらしい。ということでリダイレクトの仕組みをやり替える。まず、最初に置いた「.htaccess」を消して、わかりやすいAliasを使ってみる。httpd.confの、alias_moduleのくだりで、以下のように書いてみた。

<IfModule alias_module>
…
  Alias /laravel "C:\xampp\htdocs\laravel\public"
  <Directory "C:\sampp\htdocs\laravel\public">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
      Order allow,deny
    Allow from all
  <Directory>
</IfModule>

やってみたが、やはりトップ画面のみ表示されて、追加しても同じエラーに。いろいろググってみると、publicフォルダの「.htaccess」ファイルを修正しなければならないことが判明。「RewiteEngine On」の下に、以下を追加した。

RewriteRule ^(.*)/$ /laravel/$1 [L,R=301]
RewriteBase /laravel

とりあえずこれでタスクの追加まではうまく動いた。で、今度はタスクを削除させようとクリックすると、アプリケーション名が消えてしまう。生成されたソースを見ると、追加のformタグのactionは「http://localhost/laravel/task/」となっているのに、削除のformタグのactionは「/task/1」などとなっている。これはビューを書き換えればなんとかなりそうなので、以下のように書き換えてみた。

<!-- Task Delete Button -->
<td>
  <form action="{{ url('task')}}/{{ $task->id }}" method="POST">

とりあえず動いてくれた。今日はここまで・・・

xamppとlaravelの覚え(PHP初心者)

NetBeansインストール

私は昔Javaをやってましたが、今回はPHPの環境のみを選んでインストール。OK。
昔に比べてずいぶん軽くなっていますね。

xamppインストール

OK。ただ、MySQLのrootパスワードを変えたらPHPMyAdminが起動できなくなる。xampp\phpMyAdmin\config.inc.phpの接続情報を書き換えて解決。

Composerのインストール

https://getcomposer.org/ から取得しインストールOK。

Laravelのインストール

http://readouble.com/ のチュートリアルを参考にやってみた。

xamppのコントロールパネルからShellを起動しそこで実施。

# composer global require "laravel/installer=~1/1"

インストール完了。プロジェクト作成。

# cd htdocs
# laravel new test
# cd test
# copy .env.example .env

完了。アプリケーションキーを入れようとすると、エラー発生!

# php artisan key:generate
PHP Warning:  require(C:\xampp\htdocs\test\bootstrap/../vendor/autoload.php): failed to open stream: No such file or directory in C:\xampp\htdocs\test\bootstrap\autoload.php on line 17

どうやらプロジェクトにもcomposerをインストールせねばならないらしい。

# composer install

でもどうやら以下でやるのが一番早そうだった。インストールから暗号化キー生成まで一気にやってくれる。

# composer create-project laravel/laravel test --prefer-dist

NetBeansのプロジェクト追加

新規プロジェクトで「PHP」の「既存のソースを使用するPHPアプリケーション」を選択。
あとはソースフォルダでxampp\htdocs\test を選ぶ。PHPのバージョンは5.6にした。プロジェクトURLはそのまま。OK。一部のフォルダに赤いアラートマークがついているけど、気にしない。

早速実行。するとディレクトリツリーが表示されてしまう…

どうやら、publicというパスでデフォルトが表示されるようで。困った。

調べていたら、http://w.builwing.info/2015/05/14/xampp%E3%81%ABlaravel5%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/ で、ルートフォルダに以下のような「.htaccess」を書いて、ApacheのRewriteEngineを使って処理するとよいようで。

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteRule ^$ laravel/public/ [L]
 RewriteRule (.*) public/$1 [L]
</IfModule>

OK。デフォルトページが表示された。

とりあえずここまで。