Laravel – Userモデル

概要

Laravelプロジェクト作成時にUserモデルのapp/User.phpファイルが自動作成される。この中で、認証関係について調べてみた。

User.phpファイルの内容

app/User.phpの内容は以下のとおり。

認証関係

  • UserクラスはModelクラスを(直接には)継承していない
  • UserクラスはAuthenticatableクラスを継承している
  • AuthenticatableクラスはIlluminate\Foundation\Auth\Userのエイリアスとして定義されている。

Illuminate\Foundation\Auth\Userクラス

UserモデルクラスがAuthenticatbleクラスとして継承しているIlluminate\Foundation\Auth\Userクラスの要点は以下のとおり。

  • Modelクラスを継承している(L14)
  • AuthenticatableContractインターフェイスを適用している(L15)
    • AuthenticatableContractIlluminate\Contracts\Auth\Authenticatableインターフェイスのエイリアス(L15)
  • AuthenticatableContractインターフェイスのメソッドは、Illuminate\Auth\Authenticatableトレイトで実装(L19, L5)

同じAuthenticatableという名前でインターフェイスとトレイトがあるのがややこしい。

Authenticatableインターフェース

Illuminate\Contracts\Auth\Authenticatableインターフェイスは、識別子やパスワード、セッションに関する6つのメソッドの実装を要請する。

Userクラスでこのインターフェイスを適用する際には、エイリアスでAuthenticatbleContractという別名で扱っている。

Authenticatableトレイト

Illuminate\Auth\Authenticatableトレイトは、Authenticatableインターフェイスで要請された6つのメソッドを実装する。

要約

要約すると、プロジェクトで生成されるUserクラスはIlluminate\Foundation\Auth\Userクラスを継承することによって、

  • Illuminate\Database\Eloquent\Modelクラスを継承している
  • Authenticatableインターフェイスの6つのメソッドを実装している
    • これにより、ユーザー認証と継続セッションの機能が実装される。

通知関係

UserモデルクラスはIlluminate\Notifications\Notifiableトレイトを実装している。

属性関係

$fillable

フォームのデータをマスアサインメントで取り込むための設定。

$hidden

モデルを変換する際に、指定した属性を含めないための指定。

$cast

データベースの読み込み時にstringから特定のデータ型にキャストするための指定。

マイグレーションファイル

Userモデルクラスファイルとともに、以下のマイグレーションファイルもLaravelにより生成される。

artisan migrateコマンドで生成されたテーブルの構造は以下のとおり。

ユーザー認証

基本的なユーザー認証の設定はこちらを参照。

また、ユーザー登録処理の内容ログイン処理の内容についてはそれぞれのリンクを参照。

 

Laravel6 – ユーザー認証

 

プロジェクト開始時に作成されるファイル

Userモデル

プロジェクトを作成すると、appディレクトリー下にUser.phpが作成される。

Userモデルの内容についてはこちらを参照。

コントローラー

プロジェクトを作成すると、Controllers/Authディレクトリー下に以下の認証用コントローラー群が自動的に作成される。

ルーティング設定

ユーザー認証のためのルーティング

プロジェクト作成後にUserモデルと必要なコントローラーはLaravelにより作成されるが、ルーティングは設定が必要になる。

ルーティングファイルに以下の1行を記載すると、ユーザー認証用の各種ルーティングがまとめて定義される。

ルーティングリスト

関係するルーティングは以下の通りで、ログイン関係とユーザー登録関係が定義されている。

ビューの作成

自動作成の場合

  • php artisan ui vue --authコマンドでユーザー認証に必要なビューを作成
  • 作成されるビューはresources/views/authディレクトリー下に配置

カスタムビュー作成の場合

authディレクトリーの作成

  • resources/viewsディレクトリー下にauthディレクトリーを作成
  • 作成したauthディレクトリー下に必要なビューを定められたファイル名と内容で作成

登録用フォームビューの作成~register.blade.php

authディレクトリー下に、以下フォームを含む内容でregister.blade.phpを作成。ビュー名はLaravelが生成するコントローラーで想定されているされるため、これに合わせる必要がある。

たとえばユーザー登録フォームのビュー名はRegisterControlleruseされているRegistersUsersトレイトshowRegistrationForm()メソッドにおいて、'auth.register'として呼ばれる。

ブラウザーからURL:ドメイン名/registerでアクセスすると以下のようなフォームが表示される。

カスタマイズしていない状態で登録ボタンを押すと、URL:ドメイン名/homeにリダイレクトされる(後述のように、そのままでは404エラーになる)。

ログインフォームビューの作成~login.blade.php

authディレクトリー下に、以下のフォームを含む内容でlogin.blade.phpを作成。

ブラウザーからURL:ドメイン名/loginでアクセスすると以下のようなフォームが表示される。

カスタマイズしていない状態で登録ボタンを押すと、URL:ドメイン名/homeにリダイレクトされる。

コントローラー設定

ログイン後の画面遷移

たとえばユーザーログイン後のトップページを'posts/index'とする。

デフォルト設定~404エラー

カスタマイズしていない状態では以下の様になっているが、このままログインすると404エラーとなる。

  • ルーティングファイル→特に設定なし
  • コントローラー

このときブラウザーのURL表示はhttp://localhost:3000/homeとなっている。

方法1~コントロールファイルを変更

以下の様に$redirectToの定義を編集すると、意図したページに遷移する。

方法2~ルーティングファイルに追加

コントローラーが以下の様に生成直後の状態で・・・

ルーティングファイルに以下の1行を追加する。

なお、上記をルーティングファイルに追加すれば、コントローラーの定義は以下でもよい。

ルート名は使えない

ルート名が設定されていても、以下の表現はエラーになる(Constant expression contains invalid operations)。

ユーザー登録後の画面遷移

RegisterControllerでもデフォルトで以下の様に定義されている。

LoginControllerと同じようにルーティング設定をすることで、ユーザー登録後の遷移先を設定することができる。

ユーザー認証処理の詳細

ユーザー登録処理の内容ログイン処理の内容についてはそれぞれのリンクを参照。

2038年問題対応

Laravelでモデルの雛形を生成する場合、MySQLだと作成日時と更新日時のtimestamp型の2038年問題が内包される。

database/migrationsディレクトリー下のマイグレーションファイル、...create_users_table.phptimestampsdatetime型に修正しておくべき。

ログアウト処理

ログアウト処理についてはこちら

 

PHP – マジックメソッド – __callStatic()

__callStatic()はマジックメソッドの一つで、実行させようとしたクラスのstaticメソッドが存在しない時に呼ばれる。

以下の例では、MyClass__callStatic()メソッドのみが定義されている。__callStatic()の内容は、引数の$method$argsを表示させるようにしている。

このクラスに存在しないstaticメソッドを、引数なし、引数1個、2個で実行した場合の実行結果。引数は配列として$argsにセットされ、引数がない場合は空の配列、引数が1個の場合は要素数1(要素番号0)の配列となる。

インスタンスに対して存在しないstaticメソッドを呼んで__callStatic()が実行される場合、通常のstaticメソッドと違って'->'はエラーになる。

 

PHP – static::とself::

概要

static::self::はクラスのスタティックメソッドを指すときに使えるが、それぞれ以下のような違いがある。

  • staticはそれが実行されるときのクラスを指す
  • selfはそれが定義されたときのクラスを指す

参照:new staticとnew self

準備

以下のようにParentClassとそれを継承したChildClassを準備する。

  • いずれも同じ名前のstaticメソッドstatic_method()を持つ
  • それぞれのクラスはインスタンスメソッドparent_method()child_method()を持つ
    • 何れの内容も同じで、static::static_method()self::static_method()を実行する

クラスからstaticメソッドを呼ぶ

クラスからstaticメソッドを呼ぶと、当然それぞれに対応したstatic_method()が実行される。

親クラスのメソッドから呼ぶ

親クラスのインスタンスを作って、インスタンスメソッドparent_method()内でstaticselfstatic_method()を呼び出す場合。

親クラスのstaticメソッドしか対象がないので、いずれの場合も親クラスのstatic_method()が実行される。

子クラスのメソッドから呼ぶ

子クラスのインスタンスを作って、インスタンスメソッドchild_method()内でstaticselfstatic_method()を呼び出す場合。

staticselfとも子クラスを指し、子クラスのインスタンスメソッドが実行される。

子クラスで親クラスのメソッドから呼ぶ

子クラスのインスタンスを作って、継承元の親クラスのインスタンスメソッドparent_method()からstaticselfstatic_method()を呼び出す場合。

staticは実行時のクラスを指すため、Childクラスのstatic_method()が実行される。

一方selfは定義時のクラスを指すため、parent_method()が定義されたParentClassstatic_method()が実行される。