fuelphpでのsimpleAuthとorm¥modelの両立

PHPでWebサービスを作るときの定番の機能として、ユーザー認証があります。 FuelPHPではこのユーザー認証に便利なsimpleAuthというものがついています。 これはDBにUser情報を保存して、Sessionなどを使いアクセス制限を行うものです。 デフォルトでプログラムに組み込まれているので非常に使いやすく、便利なのですが、いくつか欠点もあります。 それが

  • プロパティの追加が難しい
  • DBに入っているUser情報をOrm¥Modelを通して使えない

というものです。 simpleAuthではデフォルトで付いているプロパティはemailぐらいで、ほんとにユーザーの認証ぐらいにしか使えません。ですが、ユーザー登録と同時に様々な情報を登録するのはよく要望にあがります。 いちおうSimpleAuthでも追加できるようになっているのですが、 デフォルトではDBのカラムにprofile_fieldsというものにserializeして代入という、なかなかに面倒な方法をとっています。 また、同時にOrm¥Modelもよく使うのですが、DBに入っているUser情報をOrm¥Modelを通して使えない、というのも個人的に欠点だと思っています。 そこで、その二つの欠点を解決すべく、Orm¥ModelでのUserモデルを作ってみました。 ※すでにsimpleAuthで認証ができている状態を想定しています。

モデルの作成

まず、orm¥modelでUserモデルを作ります。 いつもどおりoliをつかって次のコマンドを実行します。

1
oil generate model users username:varchar[50] password:string group:int email:string last_login:int login_hash:string profile_fields:text oil refine migrate

これでモデル自体は出来ました。

simpleAuthに対応する

このままではprofile_fieldsにシリアライズした値を入れたり、profile_fieldsから取り出した値をアンシリアライズしないといけないので、そこを簡単に行えるように変更します。 具体的にはgetとsetをオーバーライドし、_profile_fieldsにあればデータを取得or設定する、と言うことをやっているだけです。

1
class Model_User extends ¥Orm¥Model { protected static $_properties = array( 'id', 'username', 'password', 'group', 'email', 'last_login', 'login_hash', 'profile_fields', 'created_at', 'updated_at' ); static protected $_profile_fields = array('fname','lname','tel'); protected static $_observers = array( 'Orm¥Observer_CreatedAt' => array( 'events' => array('before_insert'), 'mysql_timestamp' => false, ), 'Orm¥Observer_UpdatedAt' => array( 'events' => array('before_save'), 'mysql_timestamp' => false, ), ); public function & get($property) { if(false !== array_search($property, self::$_profile_fields ) ){ $profile_fields = @unserialize(htmlspecialchars_decode($this->profile_fields)) ?: array(); $val = isset($profile_fields[$property])? $profile_fields[$property] : NULL; return $val; } return parent::get($property); } public function set($property, $value) { if(array_search($property, self::$_profile_fields ) ){ $profile_fields = @unserialize($this->profile_fields) ?: array(); $profile_fields[$property] = $value; $this->profile_fields = serialize($profile_fields); } return parent::set($property, $value); } }

$_profile_fieldsの値を変更すれば、DBの変更なしにユーザーの様々な属性を入れることができます。 ただ、この方法ではDBからの検索等は行えなません。 (しかし、これで十分なことも多いです) 本当はsimpleAuthのクラスを継承すればsimpleAuth側でDBのカラムが増えても対応できるのですが、 Orm¥Modelがすごい便利なので、強攻策としてこんな方法を取りました。 そのうちきちんとsimpleAuthの方も勉強して、ブログに上げたいと思います。