[メモ] 17 December 2009 はてなブックマーク - CodeIgniterのform_validationでcallbackを利用するときの注意 Twitterでつぶやく

CodeIgniterのform_validationでcallbackを利用するときの注意

CodeIgniterLogo
色々事情がありまして、PHPをやってるわけですが、今回はフレームワークとして軽量なことで話にあがるCodeIgniterを採用しています。
まあ詳しい部分は公式ドキュメントや、日本語化されたドキュメントが素晴らしいのでそちらを見てほしいわけです。

CodeIgniter - Open source PHP web application framework
http://codeigniter.com/

日本CodeIgniterユーザ会
http://codeigniter.jp/

で、本題にはいりますが、
form_validationでcallbackを利用するときのコールバックされるメソッド名に注意が必要
です。

ドキュメントどおりの場合、usernameのカスタムチェックをコールバックで行う場合には、CodeIgniterのコントローラー内において下記のように記述します。
ちなみこのクラスはhttp://localhost/index.php/formまたはhttp://localhost/index.php/form/indexで呼び出されるとしましょう。

class Form extends Controller {
function index()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'ユーザ名', 'callback_username_check');
$this->form_validation->set_rules('password', 'パスワード', 'required');
$this->form_validation->set_rules('passconf', 'パスワードの確認', 'required');
$this->form_validation->set_rules('email', 'メールアドレス', 'required');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
}

function username_check($str)
{
if ($str == 'test')
{
$this->form_validation->set_message(
'username_check', 'フィールド %s に、"test"は使えません');
return FALSE;
}
else
{
return TRUE;
}
}
}
?>
要するに、
$this->form_validation->set_rules('username', 'ユーザ名', 'callback_username_check');
function username_check($str)
$this->form_validation->set_message(
'username_check','フィールド %s に、"test"は使えません');
の部分が対応するわけです。

ところが!ですね。
CodeIgniterのコントローラの仕様上、標準状態ではコントローラーのメソッドが_(アンダースコア)で始まっていない場合は下記のようなURLで呼び出せてしまいます。
http://localhost/index.php/form/username_check
さらに標準の仕様では、メソッド名より後ろの部分にスラッシュで文字列を追加すると自動的に引数になってしまいます。
http://localhost/index.php/form/username_check/username
→ つまり $form->username_check('username');を実行したのと同じ。

まずいですね・・・・。
カスタムチェックでDBアクセスとかしてたらさらにまずいですね。

で、ぱっと思い浮かんだ対応方法としては

1、 _remapをオーバーライドしてコントローラの振る舞いを再実装する。
2、 コールバックメソッドを_(アンダースコア)付きにして、コールバック指定のところでちゃんと_(アンダースコア)を入れてやる。

の2つです。1はだるいので2がおすすめです。

さっきの場合だと下記のように修正します。
callback_(アンダースコア)_(アンダースコア)username_check
$this->form_validation->set_rules('username', 'ユーザ名', 'callback__username_check');
_(アンダースコア)username_check
function _username_check($str)
$this->form_validation->set_message(
'_username_check','フィールド %s に、"test"は使えません');

以上で、コールバックメソッドも無事に隠蔽されます。
他にうまい方法有ったり、間違っているようならご指摘してください。

Comments

Pacquiao vs Margarito wrote:

With Manny Pacquiao’s unusual training pattern, several speculators of the <a href="http://www.buzzblab.com/box...">Pacquiao vs. Margarito fight</a> assume that the pound-for-pound king is confident in winning this match....

05 November 2010 at 12:54
Bulk sms wrote:

Wonderful post - I was looking for a similar article. Thanks for sharing this article to your reader. You give very nice information about

11 October 2011 at 20:59
Best Web Hosting India wrote:

Nice Post You give very nice information.Thank you very much for this valuable post. I'm looking forward to read lots more of your articles.Thanks for sharing this article to your reader.

15 December 2011 at 17:05
Cheapest Web hosting India wrote:

Nice Post..Thank you very much for this valuable post. Thanks for sharing this article you give very nice information.I'm looking forward to read lots more of your articles.

15 December 2011 at 18:12
Bulk SMS Resellers wrote:

This blog is a very good, thanks for that good info! very useful information I want read such information a lot. I was expect this particular information for a very long time. Thanks for share this information.

06 January 2012 at 16:09

Add Comment