Hatena::ブログ(Diary)

localdisk

 

2011-05-27

30分でわかるCodeIgniterでログイン処理

twitterを眺めていて見つけました。対象としてはCodeIgniter初学者でインストールはしたことあるけど、どうやって動かすかわからない人…とかかな?

英語がわからなくてもけっこう分かりやすいですし、30分なのでだれることもなく見ることができると思います。処理に関してですが、パスワードハッシュ化してるだけなのでコピペはおすすめできません。そのうちphpassの記事を書くのでそちらを参考にしていただけると助かります。

追記

…書かなくてもとても良い記事が見つかったのでリンクしておきます。

2011-05-25

CodeIgniterで簡単メンテナンスモード

なにかしらWebサービスを作成して継続していくならメンテナンスモードの作成は必須になると思います。とはいえこういった機能にあまり時間をかけたくないですよね。CodeIgniterなら簡単にメンテナンスモードを作成できます。

フック

CodeIgniterにはフック機能というのがありまして、フレームワークの要所々々でコアをハックすることなくフレームワークの動作を変更できます。今回はこの機能を利用してメンテナンスモードを作成します。

application/config/config.php

<?php
$config['enable_hooks'] = TRUE; // フック機能を有効にする
$config['maintenance'] = TRUE; // メンテナンスモードを有効にする場合はTRUE
$config['maintenance_view'] = 'maintenance'; // メンテナンスモードで表示させるViewファイル

application/config/hooks.php

<?php
$hook['pre_system'] = array(
    'class'    => 'Maintenance',
    'function' => 'maintenance',
    'filename' => 'Maintenance.php',
    'filepath' => 'hooks',
);

上記のように書くとpre_system(システムの実行の最初)に application/hooks(filepath)/Maintenance.php(filename) の Maintenance(class) クラスの maintenance(function) がコールされます。

application/hooks/Maintenance.php

とのことですので EXT を .php に修正しました。

<?php
class Maintenance {
    public function maintenance() {
        $config = load_class('Config', 'core');
        if ($config->item('maintenance') === TRUE) {
            include APPPATH . 'views/' . $config->item('maintenance_view') . '.php';
            exit();
        }
    }
}

余談ですが、フックを作成する上で注意することを述べておきます。CodeIgniterで機能を拡張する際、一番使用頻度が高い関数 get_instance ですが使用できるタイミング的には post_controller_constructor 以降になります。それ以前のポイントでフックを作成する場合は get_instance を使用しないように注意して下さい。 上記コードで include を使用しているのは CI_Loader->view が get_instance を使用しているためです。

application/view/maintenance.php

<!DOCTYPE HTML>
<html lang="ja-JP">
    <head>
        <title>maintenance</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>maintenance</h1>
    </body>
</html>

最後に View を作成。これで終了です。簡単ですね。

今回の内容も CI Utility Package に含まれています。興味のある方はご覧ください。

2011-05-23

CodeIgniter Utility Package を作ってます

ここ最近 CodeIgniter を便利に使う記事を書いてきて、ささやかながらある程度の需要があると判断したので今まで記事にした内容をまとめて Bitbucket のアップしました。名付けて CI Utility Package。

以下の内容が同梱されています。下記エントリ内のコードを若干ブラッシュアップしているし、これからも更新されるので上記リンクを参照して下さい。

これからの予定

今後足そうと思ってるのはこんな感じ。

あと「このライブラリいれろ!」とか「こんなライブラリ欲しい!」とかあったら @までお気軽にご連絡下さい。

Enjoy!

2011-05-21

さよなら! var_dump! ようこそ CodeIgniter Profiler!

PHPer のみなさんこんにちは! 今日も元気に var_dump してますか? 僕はやってます! var_dump! var_dump!

でも CodeIgniter(以下CI) のおかけであんまり var_dump しなくなりました。せっかくなのでその方法をみなさんに向けてシェアしようと思います。

CI のプロファイラ使ってますか?

マニュアルにも書いてありますがコントローラーとかでこんな感じに書いてやればプロファイラが有効になります。

<?php
$this->output->enable_profiler();

するとブラウザにこんな感じに表示されます(画像は抜粋。ほかにもSQLHTTPヘッダ、configの値なんが表示されます)。便利!

f:id:localdisk:20110521161111p:image

必要ないときは非表示にしたい!

こんな感じのCSSJavascriptを書くと幸せになれるかも。

css/style.css
#profiler {
    background: url('../images/nav_bg_darker.jpg') repeat-x transparent scroll left top;
    padding-right: 310px;
    text-align: right;
}
js/utility.js
$(function(){
    if ($('#codeigniter_profiler').length > 0) {
        var prof = $('<div>', {
            id: 'profiler',
            html: $('<img>', {
                height: 43,
                width: 154,
                alt: 'Toggle Profiler',
                title: 'Toggle Profiler',
                src: 'images/nav_toggle_darker.jpg'
            }),
            click: function() {
                $('#codeigniter_profiler').slideToggle();
            }
        });
        $('body').prepend(prof);
        $('body').prepend($('#codeigniter_profiler'));
        $('#codeigniter_profiler').css('display', 'none');
    }
});

するとこんな感じに。

f:id:localdisk:20110521161112p:image

CIマニュアルみたいに必要なときにクリックすればスライドしてプロファイラの値が見ることができます。これでもっと便利!

リリース時には出力させたくない!

リリース時には必要ない! でもだからといってリリース時に記述を消すというのは美しくない! なので基底となるコントローラーにこんな感じの記述をしましょう。

application/core/MY_Controller.php(抜粋)
<?php
// development の場合 プロファイラを有効に
if (ENVIRONMENT === 'development') {
    $this->output->enable_profiler();
}

こうしておけばリリース時にindex.phpのENVIRONMENTをproductionと書き換えるだけでプロファイラーは出力されななくなります。もっともっと便利!

これで開発時のデバッグがかなり楽になるはずです。Let's Enjoy!

2011-05-02

CodeIgniter の Model を一工夫して使いやすくする方法

CodeIgniter の ActiveRecord はかなり使いやすいと思うのですが、ちょっと一工夫するともっと使いやすくなるよ! というのを書いてみたいと思います。僕が使ってる MY_Model はこんな感じ。

application/core/MY_Model.php

<?php

/**
 * MY_Model
 *
 * @author localdisk <info@localdisk.org>
 * @property CI_DB_active_record $db
 */
class MY_Model extends CI_Model {

    /**
     * table name
     * 
     * @var string
     */
    protected $_table;

    /**
     * constructor
     */
    public function __construct() {
        parent::__construct();
        $this->load->database();
        $clazz = get_class($this);
        $this->_table = strtolower(substr($clazz, 0, strpos($clazz, '_')));
    }

    /**
     * insert
     * 
     * @return integer 
     */
    public function insert() {
        $now = $this->now();
        $this->db->set(array('created_at' => $now, 'updated_at' => $now));
        $ret = $this->db->insert($this->_table, $this);
        if ($ret === FALSE) {
            return FALSE;
        }
        return $this->db->insert_id();
    }

    /**
     * update
     * 
     * @param integer|string $id
     */
    public function update($id, $data = null) {
        if ($data === null) {
            $data = $this;
        }
        $ret = $this->db->update($this->_table, $data, array('id' => $id));
        if ($ret === FALSE) {
            return FALSE;
        }
    }

    /**
     * delete
     * 
     * @param integer|strng $id 
     */
    public function delete($id) {
        $this->db->delete($this->_table, array('id' => $id));
    }

    /**
     * find_all
     * 
     * @return array
     */
    public function find_all() {
        return $this->db->get($this->_table)->result();
    }

    /**
     * find_list
     * 
     * @param  integer|string $limit
     * @return array
     */
    public function find_list($limit = 10) {
        return $this->db->limit($limit)->order_by('id')->get($this->_table)->result();
    }

    /**
     * find
     * 
     * @param  integer|string $id
     * @return stdClass
     */
    public function find($id) {
        $ret = $this->db->where(array('id' => $id))->get($this->_table)->row();
        return $ret;
    }

    /**
     * now
     * 
     * @return string
     */
    public function now() {
        return date('Y-m-d H:i:s');
    }
}

NetBeans で CodeIgniter のコード補完を行わせる冴えたやり方 - localdiskでも触れたように @property に CI_DB_active_record を定義しておくとコード補完が効いてコーディングが楽になります。

解説するにあたってこの MY_Model を使用する前提なんかを先に説明します。

  • モデル名は「テーブル名_model」にすること
    • User というテーブルのモデルを作成する場合のクラス名は User_model になります
  • id というカラムが存在すること
    • プライマリーキーですね。「テーブル名_id」することも考えましたが、こっちでいいかなーと。
  • created_at, updated_at というカラムが存在すること
    • お決まりの作成日時, 更新日時ですね。なんのかんのいって便利なので僕はすべてのテーブルに timestamp で定義してます。
    • updated_at は ON UPDATE CURRENT_TIMESTAMP にしてます。

さて、疲れてきたぞ…。

では、このクラスの肝だけ説明したいとおもいます。マニュアルや解説本などをみると insert/update 時にデータを配列で渡していますが別にクラスでもいけるっていうことです。以下上記 MY_Model クラスを使用した場合の Model と Controller を書いてみます。書くソースコードの量はあまり変わりませんが、かなり分かりやすく見えるんじゃないでしょうか。

application/models/sample_model.php

<?php
/**
 * Sample
 *
 * @author localdisk <info@localdisk.org>
 */
class Sample_model extends MY_Model {

    // カラムを public フィールドとして定義
    public $name;
    public $address;

    public function __construct() {
        parent::__construct();
    }

}

application/controllers/sample.php

<?php
/**
 * Sample
 *
 * @author localdisk <info@localdisk.org>
 * @property Sample_model $sample
 */
class Sample extends MY_Controller {

    public function __construct() {
        parent::__construct();
    }

    public function sample() {
        // validation などは割愛
        $this->load->model('sample_model', 'sample');
        $this->sample->name = $this->input->post('name');
        $this->sample->address = $this->input->post('address');
        $this->sample->insert();
    }
}

どうでしょう? 些細な違いかもしれませんが僕はこういう書き方がすきなのでこうしてます。