2011年8月25日

Codeigniter on fluxflex


日本人が起業したfluxflexはGithubと連動する安くて簡単なクラウド・ホスティング・サービスを目指す
http://jp.techcrunch.com/archives/20110817github-integrated-fluxflex-aims-at-making-cloud-hosting-easier-and-cheaper/
(だいぶ亀ですが・・・)現在作成中のショッピングカートをどこかでデモさせてもらえないかと探していたら、タイミングよくTechCrunchに記事が掲載されていたので試してみました。
記事が出た次の日には一時アクセスできなくなる、プライベートURLが動かないなど、まだまだ色々とこれからのサービスのようですが同じ日本人が起業したということで頑張って欲しいですね!

fluxflexの構成がApache+FastCGIの組み合わせで、index.phpをURLから削除して動作させるのに少し苦労したので、メモしておきます。

■ .htaccessを使ってindex.phpをURLから削除する on fluxflex
コンフィグのuri_protocolをREQUEST_URIに変更
code/config.php
$config['uri_protocol'] = 'REQUEST_URI';

.htaccessにRewriteBaseを追加(2行目)。
.htaccess
RewriteEngine on
RewriteBase /
RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico)
RewriteRule ^(.*)$ /index.php?/-- default controller --$1 [L]
そして最後にRewriteRuleにCodeigniterのdefault_controllerを指定して動作させることができました。
(一定の条件下では指定しなくても動作するようですが、指定した方が確実に動きます。)


fluxflexが安定稼動し、ショッピングカーとがもう少し見れるようになったらデモ用のURLをこのブログで公開します(^_^)

2011年8月19日

Codeigniter と オートロード(Autoload in PHP5)

※注:この記事はCodeigniter付属のautoloadに関するものではありません。

PHP5にはクラスのオートローディングという便利な関数(function __autoload())があります。
未定義のクラス/インターフェイスを使用しようとした時に 自動的にコールされる __autoload 関数を定義することができます。 この関数をコールすることにより、 スクリプトエンジンは、PHPがエラーで止まる前にクラスをロードする最後の チャンスを与えます。
引用元:php.net
これを使ってモデルを呼べれば楽なんですよね。そうすると
$this->load->model('model-name');
$this->model-name->function();
という書き方から以下のように普通のPHP5の書き方に変えられる。
$model = new Model-name;
$model->function();

そこで軽く調査してみたんですが、どうやら以下のサイトのような方法が多数散見されました。
6 CodeIgniter Hacks for the Masters
http://net.tutsplus.com/tutorials/php/6-codeigniter-hacks-for-the-masters/
ほうほう、config/config.phpの最後に__autoload()を入れるとな。

・・・いやいやいや、これダメだろ(゜Д゜) ??
config.phpの最後になんか入れたらログとかベンチマークとか全部こっちいっちゃうんじゃ?
ということで念のためテスト。config.phpの最後にコピーしてlog_messageで何をロードしようとしてるかチェック。

config/config.php
function __autoload($class)
{
    log_message('debug', 'Trying to load class: '.$class);
    if(file_exists(EXTPATH."models/".strtolower($class).EXT))
    {
        include_once(EXTPATH."models/".strtolower($class).EXT);  
    }
}


■ 結果

思った通り。load_class()で呼んでるものは全部オートロードに行っちゃう。この方法は採用しちゃダメな方法です。

それならどうすればいいのか?
正解はspl_autoload_registerを使う、です(断言しちゃったけど大丈夫かな?w)

オートローディングを追加するなら、ヘルパにしてautoload.phpに追加するのが一番簡単でいいんじゃないでしょうか。
(個人的にはファイルが増えるの嫌なのでLoader.phpにstaticメソッドを作ってcore/Controller.phpの最後に追加してますが)

■ spl_autoload_registerをコールするヘルパ
spl_autoload_register — 指定した関数を __autoload() の実装として登録する
http://nz.php.net/manual/ja/function.spl-autoload-register.php
引用元:php.net
サンプルヘルパ: spl_autoload_helper.php
<?php
/**
 * SAMPLE SPL Autoload Helper
 * ファイル名、メソッド名は適宜修正してください。
 */
 
function sample_loader($class) 
{
	if(file_exists(APPPATH."models/".strtolower($class).EXT))
	{
		log_message('debug', 'Load '.$class.' models in php5 style');
		include_once(APPPATH."models/".strtolower($class).EXT);  
	}
}
 
spl_autoload_register('sample_loader');
上記ではモデルだけ追加してますが、ライブラリもヘルパも追加することが可能です。
$this->load->model(~~~) とか面倒な人向けの方法でした。