YiiはWebフレームワークに非ず。その気になれば大概の事は指先ひとつでダウンさ。つまるところコマンドラインで動けば大概のことはできるのでYiiの便利なとこつまみ食いして使いましょうということ。
手抜きのためにテーブルを作ってActiveRecordを使います。以下のようなテーブルを作ります。
CREATE TABLE `bot` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`nickName` varchar(32) DEFAULT NULL,
`realName` varchar(32) DEFAULT NULL,
`server` varchar(128) DEFAULT NULL,
`port` int(11) DEFAULT NULL,
`channel` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
対応するモデルが以下のようになります。今回つかうIRCライブラリはPEARのNet_SmartIRCです。だいぶ古臭いのですが、なんとか動かせるのと、特定のメソッドさえ持っていればどんなインスタンスでもBOTにできる自由度の高さがあります。
<?php
class Bot extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'Bot';
}
public function timer($irc)
{
//10000ms毎に叩かれる
}
public function hello($irc,$data)
{
$irc->message(SMARTIRC_TYPE_NOTICE, $data->channel, 'こんにちは');
}
public function reserveMessage($irc, $data)
{
//すべてのメッセージをうけとるので保存とか返事とかいろいろできる
}
}
ひとまずBotのために必要なメソッドtimer()
とreserveMessage()
とサンプルがてらhello()
を用意します。
こいつをコマンドで起動させるためにコンソール用のクラスを作ります。command/RunCommand.php
を作成すると、protectedの下にあるyiic
を利用して
./yiic run
と呼び出せます。ちなみにこの時標準でconfig/console.php
の設定を参照します。config/main.php
とは全く別の設定になるので、DBの設定と、importにmodels.*を追加しましょう。
<?php
…
//追加
'import'=>array(
'application.models.*',
'application.components.*',
),
…
'components'=>array(
// DBの設定
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=hoge',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
),
…
さてコンソールコマンドを作ります。CConsoleCommand
を継承するとyiicから呼ばれた際、run()
が実行されます。
ちなみに先頭の不可解な$GLOBALS
の定義はyiiから呼ぶ際にどうやら変数のスコープがおかしくなってしまうのでそれを埋めるべく定義しなおしてます。まあPHP4時代からのライブラリなので諦めましょう。もしくはPHP5向けのナウくて自由度の高いライブラリおしえてください。
<?php
require_once("Net/SmartIRC.php");
$GLOBALS['SMARTIRC_nreplycodes'] = $SMARTIRC_nreplycodes;
class RunCommand extends CConsoleCommand
{
public function run()
{
$bot = Bot::model()->findByPk(1);
$irc = new Net_SmartIRC();
//10000msec毎に$bot->timer()を呼ぶ
$irc->registerTimehandler(10000, $bot, 'timer');
//チャンネルメッセージがパターンに一致したら$bot->hello()を呼ぶ
$irc->registerActionhandler(SMARTIRC_TYPE_CHANNEL, '^hi$', $bot, 'hello');
//すべてのメッセージを$bot->reserveMessage()に渡す
$irc->registerActionhandler(SMARTIRC_TYPE_ALL, '.*', $bot, 'reserveMessage');
$irc->connect($bot->server, $bot->port);
$irc->login($bot->name,$bot->name);
$irc->join($bot->channel);
$irc->listen();
}
}
動作としてはNet_SmartIRCオブジェクトにイベントハンドラを登録すると、指定のメソッドが呼ばれるだけの簡単なしくみなので、先ほどのBotモデルのメソッドが呼ばれるようにします。
これでコマンドを叩くだけでBOTが起動して指定のサーバーのチャンネルに入ります。
./yiic run
ただしこの状態だと起動しっぱなしなので、バックグラウンドで実行させるとか、プロセスをフォークしてから起動して死ぬとかするようにしないとちょっと勝手がわるいかもしれません。
サンプルがいい加減なので何がしたいんだコレ感あるかもしれませんが、Yiiのプロダクトに載せればIRCをインターフェイスにして情報を取得したり保存したり、何かしらを通知させることもできたりと結構使えます。
YiiのコンポーネントやARはWebでなくても使い勝手がよいので、CUIツールのフレームワークとしてもいい働きをするんじゃないでしょうか。