バリデーションの表示言語を日本語に設定する
1.classes/lang/
以下にjaというフォルダを作成する
2.ja
の中にvalidation.php
というファイルを作成する
3.fuel/app/config/config.php
でバリデーションの文字を日本語に設定
/**
* Localization & internationalization settings
*/
'language' => 'ja', // ここがデフォルトではenなのでjaに設定(1.で作ったフォルダ名と同じならじゃなくても良い)
// 'language_fallback' => 'en', // Fallback language when file isn't available for default language
// 'locale' => 'en_US', // PHP set_locale() setting, null to not set
4.以下のように出力したいバリデーションメッセージを設定
<?php
return array(
'required' => ' :label 欄は必須です。',
'min_length' => ' :label 欄は :param:1 文字以上にしてください。',
'max_length' => ' :label 欄は :param:1 文字を超えないようにしてください',
'exact_length' => 'The field :label must contain exactly :param:1 characters.',
'match_value' => 'The field :label must contain the value :param:1.',
'match_pattern' => 'The field :label must match the pattern :param:1.',
'match_field' => 'The field :label must match the field :param:1.',
'valid_email' => 'The field :label must contain a valid email address.',
'valid_emails' => 'The field :label must contain a list of valid email addresses.',
'valid_url' => 'The field :label must contain a valid URL.',
'valid_ip' => 'The field :label must contain a valid IP address.',
'numeric_min' => 'The minimum numeric value of :label must be :param:1',
'numeric_max' => 'The maximum numeric value of :label must be :param:1',
'numeric_between' => 'The field :label must contain a numeric value between :param:1 and :param:2',
'valid_string' => 'The valid string rule :rule(:param:1) failed for field :label',
'required_with' => 'The field :label must contain a value if :param:1 contains a value.',
'valid_date' => 'The field :label must contain a valid formatted date.',
);
CSRF対策
データを送信するformに以下を記述する
<?php echo Form::csrf(); ?>
POST値取得側でtokenのチェックを行う
if ( !Security::check_token() ) {
echo "ページ遷移が不正です";
}
例外を自分で設定する
FuelPHPには404 Not Found用 HttpNotFoundExceptionクラスと500エラー用のHttpServerErrorExceptionクラスがある
自作のエラー処理クラスを作成したい場合はHttpExceptionクラスを継承する
1.自作エラー処理関数を作成
class MyHttpException extends HttpException
{
public function response()
{
return \Request::forge('error/invalid')->execute([$this->getMessage()])->response();
}
}
2.エラー表示画面の作成
class Controller_Error extends \Controller_Template
{
public function action_invalid($message = null)
{
if ( $message === null ) {
return '不正なデータです';
} else {
return e($message);
}
}
}
3.自作エラー処理を使う
throw new MyHttpException('正しいページ遷移で来てください');
これはFuelPHPのHMVCという機能を使用したパターンです
自分のアクション以外のアクション結果を返せます
1.のforgeで使用するページを指定します ('error/invalid') invalidへのルーティングが必要な時は追加しておきましょう
executeで'正しいページ遷移で来てください'というメッセージを引数にとってinvalidにリクエストを送ります
その結果をresponseで取得し表示します
modules以下のclassesのパスについて
modules/user/classes/controller
/model
/view
modules/user/classes/
一番下に記述しているclasses直下にファイルを作成した時
checkvalidate.phpとかを作成した場合
テストに記述するパスは
user\CheckValidateになる
異なるフォームの値が同じかどうかのバリデーションを掛けたい時
add_ruleでmatch_fieldを使う
// メールアドレス入力
$val->add('email', 'email')
->add_rule('required')
->add_rule('match_field', 'confirm_email');
// 確認用メールアドレス入力
$val->add('confirm_email', 'confirm_email')
->add_rule('required');
emailとconfirm_emailの入力が一致していない場合は警告が出る
カスタム(独自)バリデーションの作成
作成手順
- カスタム(独自)バリデーションクラスの作成
- Validation::forgeのadd_rulesメソッドでカスタムバリデーションを追加
- 2.で追加したバリデーションにaddcallableメソッドでカスタムバリデーションクラスを追加
-
lang/~/validation.php
にバリデーション追加
の手順
1.カスタムバリデーションクラスの作成
規約としてバリデーションメソッド名は「validation」で始めないといけません
class CustomValidation
{
// 値が5の時だけバリデーションを通す
public static function _validation_number_five($value)
{
if ( $value === 5 ) return true;
else return false;
}
}
2.Validation::forgeのadd_rulesメソッドでカスタムバリデーションを追加
public function action_input_five()
{
$val = \Validation::forge();
$val->add('number', '数字')
->add_rule('required')
->add_rules('number_five'); // バリデーション追加
}
3.2.で追加したバリデーションにaddcallableメソッドでカスタムバリデーションクラスを追加
public function action_input_five()
{
$val = \Validation::forge();
$val->add('number', '数字')
->add_rule('required')
->add_rules('number_five')
->addcallable('CustomValidation'); // カスタムバリデーションクラスを追加 ※多分出来る
}
4.lang/~/validation.php
にバリデーション追加
<?php
return array(
'required' => ':labelは必須です。',
'min_length' => ':labelは:param:1文字以上にしてください。',
'number_five' => ':labelは5しか認めません。', // バリデーション名とメッセージ追加
);
パッケージを読み込みたいとき
パッケージ名はpackages/ 下のフォルダ名だと思う
\Package::load('パッケージ名');
コンフィグを読み込みたいとき
\Config::load('ファイル名',true);
oil generate adminで管理画面を作成し、生成されたcontrollerをmodules以下のディレクトリに移してにlogin画面を開こうとした場合にリダイレクトループになる現象を回避する方法
ここのソースです
controllers/admin.php
Request::active()->controller !== 'Controller_Admin' or ! in_array(Request::active()->action, array('login', 'logout'))
このコードの前で\Request::active()->controller
と\Request::active()->action
を出力して値を確認しましょう
もしファイルをapp/modules/mydirectory/classes/controller
ディレクトリを移した場合
本来Controller_Admin
という値が取得されるはずがmydirectory\Controller_Admin
となっていてif文の条件で無限にfalseと判定され続ける
ので
\Request::active()->controller !== 'Controller_Admin'
を
\Request::active()->controller !== 'mydirectory\Controller_Admin'
みたいに変更すればログイン画面に遷移できるはず
modulesの中のモデルのリレーションを設定したい時に、別モデルを指定する
model_to
の中を単純にモデル名だけ指定すると、そんなモデルは見つからないと怒られます
'model_to' => 'Model_Category',
ので以下のようにnamespace\モデル名
とする
protected static $_belongs_to = array(
'trn_faq_category' => array(
'key_from' => 'faq_category_id',
'model_to' => 'backend\Model_FaqCategory',
'key_to' => 'id',
'cascade_save' => true,
'cascade_delete' => false,
)
);
モデルのリレーションにbelongを追加するときは対応するモデルにhas_oneを追加しなければいけない
モデル全体で物理削除をしたくないときはOrm\Modelを継承するのではなくOrm\Model_Softを継承する
ORMでクエリを発行した際のクエリを表示するメソッド
DB::last_query();
ORMのrelatedでjoinsしたテーブルの条件を検索条件に使う場合
->where('リレーション.カラム名', $val)
relationで取得したオブジェクトからjoinしたデータを取得する
$related_user = ->related('game')
$related_user->game->score;
ORMで取得するカラムを指定する場合
->select('id', 'status_type')
指定条件で1件のみデータを取得する
public static function get_first_user_by_search_criteria($search_data = [])
{
$user_info = self::query()
->related('user_status')
->where($search_data)
->get_one();
return !empty($user_info) ? $user_info : [];
}
ORMqueryのwhereに連想配列で検索条件のカラムを入れる時のrelationしているテーブルのカラム指定方法
例えば以下の関係(親テーブルはuserとする)の時に
$user_info = self::query()
->related('user_status')
->where($search_data)
->get_one();
whereの条件をuser_status.birthday
としたい場合
$search_dataに入れる時の記述方法は
[
`user_status.birthday` => $date
]
となる
もしuser_statusに関連するuser_detailのようなテーブルがあった場合
その指定方法は
[
`user_status.user_detail.hoby` => $hoby
]
のように
リレーションテーブル.その先のリレーションテーブル.カラム
となる
リレーションが深くなっても.
で繋げば条件を指定できる
コアクラスを拡張する
コアクラスを継承する時は同じクラス名で継承した後、fuel/app/bootstrap.php
のAutoloaderに継承したファイルを追記しなければならない
例えばCrypt
クラスを拡張したいとして
fuel/app/classes/mycrypt.php
を作成したとする
<?php
// Cryptという同じ名前で継承
class Crypt extends \Fuel\Core\Crypt
{
// 追加した関数
public static function ee($str)
{
echo $str . "\n";
}
}
eeというメソッドを追加しました(適当
クラスの拡張は済んだので次はbootstrap.php
の編集
\Autoloader::add_classes(array(
// Add classes you want to override here
// Example: 'View' => APPPATH.'classes/view.php',
// ここに追記
// '拡張クラス名' =>
'Crypt' => APPPATH.'classes/mycrypt.php',
));
これで
Crypt::ee("拡張成功");
とかすればeeメソッドが使用できると思います
元のCrypt
クラスを使いたい場合は
\Fuel\Core\Crypt::encode("~~");
みたいにパスを指定してあげれば使えます
ViewでCSSや画像の読み込み
Assetクラスを使う
public/asset
以下のファイルを読み込む場合は
<?php echo Asset::css("bootstrap.min.css"); ?>
のようにAsset::css
を使う
public/css/css2/
以下のファイルを読み込む場合は
<?php echo Asset::css("css2/bootstrap.min.css"); ?>
ディレクトリを追加しましょう
Authコマンドの実行
oil console
>>> Auth::create_user('admin', 'password', 'example@co.jp', 100);
既にログインしている状態なので未ログイン時に見せるページを表示させたくない場合
例えばログインしていない時に見せたいページhttps://myservice/notlogin
にログインしているユーザが遷移してきた場合、ログイン状態の初期ページに飛ばしたい
https://myservice/top
とか
// redirectでtopに飛ばす
\Auth::check() and \Response::redirect('top');
Modelでsaveした時の挙動
$user = Model::forge();
$user->name = 'バイバイまさや選手権';
$res = $user->save()
var_dump($res);
var_dump($user);
ここの$res
はbool型でinsertに成功しかたの結果を返します。
次に$user
はそのモデルのプロパティが入ります、id
がauto_incrementだったら勝手にidが入ってくれます。
DBトランザクションを実現する
try
{
DB::start_transaction();
// 何らかのクエリ...
DB::commit_transaction();
// クエリの結果を返す
}
catch (Exception $e)
{
// 未決のトランザクションクエリをロールバックする
DB::rollback_transaction();
throw $e;
}
トレイトを使用する
手順は
- トレイトを定義する
- bootstrap.phpにロードするファイルを追記
- 実際に使う
modules下とかclasses下のモデルで定義する場合によって微妙に変わるかもしれませんが
今回はfuel/app/classes/model/model_base.php
にトレイトクラスを定義しました
1.トレイトを定義する
<?php
trait ModelBase
{
public function getValue($column)
{
return $this->$column;
}
public function setValue($column, $value)
{
$this->$column = $value;
}
}
2.bootstrap.phpにロードするファイルを追記
<?php
// Bootstrap the framework DO NOT edit this
require COREPATH.'bootstrap.php';
\Autoloader::add_classes(array(
// Add classes you want to override here
));
// Register the autoloader
\Autoloader::register();
\Fuel::load(APPPATH.DS.'classes/model/model_base.php');
3.実際に使う
トレイトのメソッドを使いたいクラス内で使えるように宣言します
<?php
class Model_Hoge extends \Orm\Model
{
// 使うトレイトを宣言
use \ModelBase;
}
$hoge = Hoge()::forge();
$hoge->getValue('name');
moduleのconfig下にコンフィグファイルを置いてそれを読み込みたい場合の設定
fuel/app/config/config.php
のalways_load
のconfig
に読み込ませたいmoduleとconfigファイルを指定する
'always_load' => array(
'config' => array(
'app',
'const',
'CustomModule::customauth' => 'customauth', // ここがコンフィグ読み込ませる設定
),
),
\Config::get
で使う場合は
\Config::get('customauth.~~~')
のように使える
FuelPHP で modules 利用時の config 設定について整理
Sessionの有効期限を設定しているファイルと変数
まずファイルは
fuel/core/config/session.php
// 変数はこれ
// session expiration time, <= 0 means 2 years! (optional, default = 2 hours)
'expiration_time' => 7200,
秒単位での設定なのでセッションを3秒で切りたいときは3、1時間に設定したいときは3600とかに設定しましょう
ローカルでは動作していたが、検証用サーバーに持っていくとクラスが見つからないという旨のメッセージを受けた場合
その呼び出し元PHPファイル名に大文字が入っていないか見る
FuelPHPのファイル名は全て小文字だが、大文字小文字を解決できるファイルシステムだと大文字でも通ってしまって本番などにあげたときに動かなくなることがある
Undefined variable: titleのようなエラー
上記のようなエラーが出て、エラー箇所が$this->template->titleみたいなテンプレート関連だったら
まずはそのコントローラがController_Templateなどを継承しているか確認する
templateが使えないので使えるようにしていけば良い
Controller_Templateを継承したクラスを継承してコントローラを実装した場合before()などでparent::before();などをするように
1つのルーティングされているアクションで2つのルーティングされていないアクションを呼び出す
例えば1つのルーティングだけどログイン状態によって表示したいViewや処理を変更したい時に、全ての処理を1つのアクション内に突っ込むのはダサいので違うアクションを呼んで表示項目を変更しようという目的
ルーティングの設定
'_root_' => 'top/index'
ユーザーがアクセスするルーティングされているアクション
public action_index()
{
if ( self::isLogin() ) {
// forgeにfalseをつけることでルーティングに設定されていないアクションを呼び出せる
// その時の指定パスはルーティング定義の'' => 'こっちに書く方' を指定する
$this->template->content = \Request::forge('top/top', false)->execute()->response();
} else {
$this->template->content = \Request::forge('guest/top', false)->execute()->response();
}
}
2つのルーティングされていないアクション
public function action_top()
{
$values = [
'posts' => [],
'errors' => [],
];
$this->template->title = 'あなたはログインしていますね。';
$this->template->content = \View::forge('top/index', $values);
}
public function action_top()
{
$values = [
'posts' => [],
'errors' => [],
];
$this->template->title = 'あなたはログインしていません。';
$this->template->content = \View::forge('guest/index', $values);
}
1つ目のアクションは別々のアクションを呼び出すための振分け役で、他のルーティングされていないアクションが表示する本体
ルーティングされていないアクションはURLからはアクセス出来ない
URLからアクセスさせないようにするのはルーティングに書かないのが一番いいが、\Request::is_hmvc()
という関数を使えばURLからアクセスされた場合とアクションから呼び出された場合の処理を振分けることが出来る
if(\Request::is_hmvc())
{
// HMVCだった場合の処理
}
else
{
// それ以外
}
TESTを実行するときにCould not find asset: bootstrap.css
のようなエラーを吐く場合の対策
解決策としてはfuel/app/config/
以下にasset.php
を配置して'fail_silently' => true,
を記述する
※module用の設定ファイルはfuel/app/モジュール名/asset.php
return [
'fail_silently' => true, // Test時のファイル名解決できない問題を解消する
];
TESTクラスに自作のメソッドをtraitで追加したい時
- Traitを作成
- クラスの外でuse宣言
- テストメソッド内でtraitのメソッドを使う
2.の宣言方法はこんな感じ
useをクラス内で宣言出来なかった
use path\MyTestTrait as MyTestTrait;
class ~~~~_Test extends \TestCase
{
public function test_myprocedure()
{
MyTestTrait::originalMethods();
{
}
Fuel標準ではないモジュールをcomposerインストールした時のクラスの使い方
composer updateした後にvendor下に指定のライブラリが入っていることを確認する
基本的に外部ライブラリは使うときにuseなどで読み込む必要な無い
new \GuzzleHttp\Client([
みたいに
fuel/coreを削除したコミットをして、その後にcomposer.phar updateをかけるが上手くファイルが落ちてこない時の確認項目とその後のインストール
まずfuel/core
やfuel/package
下の各ディレクトリが空になっていないか確認する
ここにディレクトリが存在しているとcomposer.phar updateなどをした時にディレクトリが存在すると勘違いされその下のファイルが入ってこない
ので
rm -rm fuel/core
rm -rm fuel/package/~~~
を実行してから
ファイルを取得するために
php ./composer.phar install
これで無くなったファイルが再び入ってくる