Hatena::ブログ(Diary)

kunitの日記 このページをアンテナに追加 RSSフィード

2011/10/01 (土)

[][] 受け身ではなく手を動かすイベントの楽しさ 17:53  受け身ではなく手を動かすイベントの楽しさを含むブックマーク

もう10月ですねぇ。いよいよ開催が再来週と迫ってきた PHPMatsuri 2011の リレーブログです。

昨日の @tanakahisateru さんの PHPMatsuri 2010 からの1年を振り返って からバトンをうけて書きます。

このリレーブログ、今まで書かれている内容がかなり熱い内容なので、ぜひご一読を!

PHPMatsuriでできること

PHPMatsuriはセミナーや勉強会と違って参加者が手を動かすことを基本としたイベントです。セミナーや勉強会で自分の知らなかった情報を得るのも楽しいのですが、自分でそれを身につけるにはやはり自分で手を動かすことが一番だと思います。(PHPMatsuriではセミナー形式のセッションも並行で行われますが、それを聞くのも良し、聞かずにもくもくとコードを書き続けるもよし、それは参加するあなたの自由です)

また、普段の仕事では使っていないフレームワークやライブラリを使っていろいろ試すということをとことんできる場だと思います。ここ数年symfomy 1.XやCakePHP 1.Xを使って仕事をしてきた人(自分もそうですが)にとって、Symfony 2やSilex、CakePHP 2.XやLithiumといったこれから主力となりそうなフレームワークでいろいろ試す絶好の機会です。

そして、PHPMatsuriではこれらのフレームワークの開発者が来日→参加するので、ちょっとした疑問でもばんばん聞けてしまうというまたとないチャンスとなります。日本にいながらにしてそれぞれのフレームワークの哲学を開発者本人から聞けてしまうというのは本当にすばらしいことだと思います。

昨年のPHPMatsuri 2010では結構夜遅くまで開発者の方々がメインの部屋に残られていたので、ちょっと勇気をだせばいくらでもお話が聞けると思いますよ。

PHPMatsuriの雰囲気

自分は昨年のPHPMatsuriからの参加で、しかも午前中に別の用事があったため、午後からの参加となったのですが、会場に着いたときになんとも言えない雰囲気にびっくりした覚えがあります。全員がノートパソコンを開いて周りと時には会話をしながらそれぞれがコードを書いている姿は今でも忘れられません。

その中に一度飛び込んでしまえば好きなだけコードを書いていられるというか、それぞれ別のことをしてるはずなのに独特の一体感があってコードを書く人にはたまらない雰囲気だと思います。

結局昨年は部屋にはもどらずずっとメインとなった会場で朝までコードを書いていたのですが、もっと時間があればなぁと思うくらいの充実感でした。

関西で行われる意義

個人的には今回のイベントでうれしいと思うところ。関西出身者としては関西でのイベントが少しでもふえてほしいなぁと思っていて、こういうイベントが関西で行われるってのは本当にうれしい。

PHPMatsuriのように超大物をゲストに呼んでとかになるとスタッフの皆さんが大変ご苦労されていると思うのですが、みんなが集まって一晩中コードを書こうぜ!ということなら場所さえあればできちゃうわけで、是非ともいろんなところで開催されてほしいですね。

来年はまた違う場所で行われるといいですよね。

手を動かしたら発表しよう

PHPMatsuriのいいところは、手を動かした結果をみんなの前で発表する場があるってこと。自分が作ったモノなんてたいしたことないなんて思わずに、ひとまず発表してみるってのがいいと思います。自分が普段当たり前だと思っていることが意外と周りの人からすると当たり前でないことが多いわけで、周りの人も何より自分自身でなにか発見するモノがあると思います。

まずは参加してみよう

だらだらと書きましたが、こんな楽しそうなイベント、チケットを購入すればいつでも潜り込むことができますよ。興味を持った方は是非チケットを購入して参加してみてください。

次は @k1Low さんがいらっしゃる Fusic さんのブログにつなぎます。よろしくお願いします。

トラックバック - http://d.hatena.ne.jp/kunit/20111001

2011/04/10 (日)

[][] Yammer for ガラケー ソース公開 22:07  Yammer for ガラケー ソース公開を含むブックマーク

Twitterでちょこちょこツイートしていたんだけど、震災以後作っていたYammerにガラケーからアクセスするためのゲートウェイとなるアプリケーションのソースをgithubで公開しました。

github - Yammer for Keitai

#いろいろソースを整理したりするつもりだったけど、大江戸Ruby会議から帰ってきて爆睡をしてしまったので、もうそのままでいいやってことでpushしてます...

CakePHPでささっとつくったもので、YammerのAPIをたたいているだけで、そんなにたいしたことはやってないです。

まぁ、今までガラケーでアクセスできなかったYammerがそれなりにつかえるようになるので、自分たち的には便利に使い始めてます。

で、この公開したソースを使ってどのようにサイトを構築するかの手順ですが、さらっと書こうと思ったらなにげにいろいろやらないといけないので、きちんとまとめてあとで書きます。すみません...

[][] Yammer for ガラケー でなにをやってるか? 22:32  Yammer for ガラケー でなにをやってるか?を含むブックマーク

構築手順の説明の前にこのアプリでなにをやっているかを書いときます。

YammerのAPIをたたくためにOAuthを使って権限を取得しないといけないんですが、その取得の流れのURLがガラケーからは現状たたけないので、以下のような流れにしてます。

  1. ユーザにメールアドレスとパスワードをいれてもらう(このときのメールアドレスとパスワードはこの携帯サイトへのログインで使用するためのもので、Yammerのサイトで設定してあるものとまったく別物でかまわない)
  2. 入力してもらったメールアドレス宛にYammerのauthorizeのURLが入ったメールを送信する
  3. そのメールをPCでうけとってもらって、そこに入っているURLにPC側でアクセスして、アプリのアクセス許可をだす
  4. アクセス許可を出すと4桁のverifierが入手できるのでそれを携帯サイト側で入力する

1番目で入力したメールアドレスとパスワードでこのアプリにログインするとYammer APIを使用してメッセージを取得したりできるようになるので、なんかややこしい動きなのはこの権限を取得するところだけになります。

こんな流れになっているので、このアプリに保存される(デフォルトではSQLiteに保存してる)データはこのサイトにログインするためのメールアドレス/パスワードとOAuthで使用する各種キー/シークレットだけです。今のところメッセージやユーザ一覧等はその都度APIでとってきてるので、モバツイみたいにキャッシュして賢くなんやかんややってくれるとかはしてないです。(ユーザやグループの画像はそのまま使うとでかすぎるのでリサイズをする関係上キャッシュしてる形になってます)

アプリのセットアップをするためには携帯からWebアクセスできるだけではだめで、メールを送信して権限設定をするので、サーバからメールが送信できるように設定しておかないといけないです。(今のところそのサーバで外部からメールを受け取れるようにする必要はないです。将来的にはメールを使って画像付きメッセージ投稿とかできるようにするかもしれないので、そのときには必要になると思いますが)

[][] セットアップ手順(不親切版) 23:26  セットアップ手順(不親切版)を含むブックマーク

とりあえず試したいという人がいるかもしれないので、ある程度自力でいろいろできる人向けのセットアップ手順を書いときます。(もっと親切なものは後から書くかもしれない)

サーバを準備する

EC2やNiftyクラウド、さくらVPSとかでサーバを準備してください。注意事項としてはPHPのバージョンは5.2以上じゃないといけないです。

あと、一つ前のエントリで書いたようにメールが外部に送信できるようにしておいてください。

追記
ローカル環境にセットアップして、Firefox+Firemobilesimulatorとかで動作を試してみるってのがいいと思います。

ソースをgithubからとってくる

適当なディレクトリにソースをとってきてください。(例で使っているディレクトリはあくまで例です)

  cd /home/www
  git clone https://github.com/kunit/yammer.git
  cd yammer
  git submodule init
  git submodule update

YammerからOAuthのConsumer Key/Secretを取得して設定する

YammerのAPIをたたくために以下の手順でアプリケーションの登録を行って、Consumer Key/Secret を取得してください。

  • ガラケーでアクセスしたいネットワークのアカウントでYammerにログインする(※注意1)
  • http://developer.yammer.com/api/ にアクセスする
  • その画面の右上の Register Application のリンクをクリック
  • アプリケーションの情報を入力する。Application名は「Mobile Yammer for xxx」の形式にしていると他のものとかぶらないでいいと思う。(※注意2)
  • 入力してsubmitすると Consumer Key/Secret が発行される

(※注意1) YammerのOAuthの権限はネットワーク毎に発行されます。そのためログインしないとアプリケーションの登録作業ができないです。

(※注意2) このアプリケーション登録情報は今のところ後から変更できないっぽいので適当につけると後で泣きをみます

上記の手順で登録した内容を設定ファイルを作成して記述します。

  cp app/config/yammer.php.default app/config/yammer.php

yammer.php で設定するのは以下の4つです。

Yammer.oauth_mail_from
権限設定メールを送信するときのFrom
Yammer.oauth_mail_subject
権限設定メールを送信するときのSubject
Yammer.oauth_key
取得したConsumer Key
Yammer.oauth_secret
取得したConsumer Secret

CakePHPのセキュリティーの基本設定をする

core.phpをコピーしてつくってください。

 cp app/config/core.php.default app/config/core.php

core.phpの以下の2つの値を変更してください。(これはCakePHPの通常のセットアップでやることと同じなので、なんのこっちゃと思った場合は適当にぐぐってください。すみません)

  • Security.salt
  • Security.cipherSeed

テーブルを作成する

以下のコマンドを実行してテーブルを作成してください。実行するとy/nで答えるものが2つ出ますが、それらはEnterを押してデフォルトの答えのままで大丈夫です。

  cake/console/cake schema create

書き込み権限の付与

app/tmp 以下はWebサーバから書き込みができるように権限を変更してください。

  chmod -R a+w app/tmp

Webの公開設定

app/webroot をDocument RootとなるようにWebサーバの設定をしてください。また、.htaccessで設定が上書きできるようにしてください(このあたりはCakePHPの設定と同じです)

ここまでやれば(たぶん)つかえるはず。

...と書いてみたんですが予想通りとてつもなく不親切だなぁ。ファイル展開したらすぐ使えますとかになればいいんだろうけど、いくつかは設定してもらわないといかんし。これでどれくらいの人ができるかってのを様子を見ながらセットアップ手順の簡略化は考えます。

トラックバック - http://d.hatena.ne.jp/kunit/20110410

2010/12/19 (日)

[][] ControllerからModelを使用するいくつかの方法 (CakePHP Advent Calendar 19日目) 00:46  ControllerからModelを使用するいくつかの方法  (CakePHP Advent Calendar 19日目)を含むブックマーク

CakePHP Advent Calendar 2010 はみなさんのノウハウがいろいろと知ることができてほんと楽しいですね。

18日目のhaltさんのauthkittenプラグインで子猫認証 (CakePHP Advent Calendar 2010 18日目) を引き継いで、19日の記事となります。


※本日の記事は CakePHP 1.3.6 がベースになっています。

ControllerからModelを使用する方法ですが、一番手軽なのはControllerの「usesプロパティ」だと思います。

usesプロパティは以下の流れでモデルをロードします。

  • Dispatcher#dispatch (webroot/index.php)
  • Dispatcher#_invoke (cake/dispatcher.php)
  • Controller#constuctClasses (cake/libs/controller/controller.php)

Controller#constructClasses のソースは以下のようになっています。

function constructClasses() {
  $this->__mergeVars();
  $this->Component->init($this);

  if ($this->uses !== null || ($this->uses !== array())) {
    if (empty($this->passedArgs) || !isset($this->passedArgs['0'])) {
      $id = false;
    } else {
      $id = $this->passedArgs['0'];
    }

    if ($this->uses === false) {
      $this->loadModel($this->modelClass, $id);
    } elseif ($this->uses) {
      $uses = is_array($this->uses) ? $this->uses : array($this->uses);
      $modelClassName = $uses[0];
      if (strpos($uses[0], '.') !== false) {
        list($plugin, $modelClassName) = explode('.', $uses[0]);
      }
      $this->modelClass = $modelClassName;
      foreach ($uses as $modelClass) {
        $this->loadModel($modelClass);
      }
    }
  }
  return true;
}

最初のif文をよく見ると「!==」でチェックをしていて、Contrrolerでモデルをロードしたくなければ、厳密に「null」か「array()」でなければならないということがわかります。(モデルを使用しないつもりで false を代入してもダメなのはこのせいです)

usesプロパティが false(usesプロパティを指定してない場合も false になる) だと $this->modelClass を使用してモデルをロードします。($this->modelClass はデフォルトでは Controller 名から作られるもので UsersController なら User になるといった規約になります)

usesプロパティに対して配列指定でモデル指定した場合、1つめに設定した値を特別扱いし、$this->modelClassを上書きしています。複数指定する場合、適当に指定していいのではなくて、1つめは特別な意味を持つことを覚えておく必要があります。

さて、モデルのロードで使用されている Controller#loadModel ですが、これはフレームワーク内部だけで使われるものではなくて、我々が普段作成しているControllerの中でモデルをロードしたいときに使えるメソッドになります。(loadModelはCakeBookの「3.5.4.4.7 loadModel」にきちんと説明されています)

class FooController extends AppController {
  public function index()
  {
   // これで $this->Bar->... という形でモデルが使用できる
    $this->loadModel('Bar');
  }
}

Controllerで複数モデルを使用するときにusesに指定してしまうと、モデルを使用しないActionでも全てのモデルをロードしてしまうので、usesに指定するのは全Actionで使用するものだけにし、それ以外は loadModel でロードするのが効率がいいということになります。

Controller#loadModel のソースを見ると、ClassRegistry#init を使用してモデルクラスを生成しています。ClassRegistry#init 内でモデルクラスを生成しているソースの部分を抜き出してみます。(内部的にいろんなことをやってくれてるんですが、今回は説明に必要な部分だけ抜き出します。ClassRegistryに関しては id:hiromi2424 さんの「ClassRegistry徹底解剖」が参考になります)

  if (class_exists($class) || App::import($type, $pluginPath . $class)) {
    ${$class} =& new $class($settings);
  } elseif ($type === 'Model') {
    if ($plugin && class_exists($plugin . 'AppModel')) {
      $appModel = $plugin . 'AppModel';
    } else {
      $appModel = 'AppModel';
    }
    $settings['name'] = $class;
    ${$class} =& new $appModel($settings);
  }

ここで重要になってくるのが elseif の方で、うまくクラス生成ができなくて、さらにそれが Model だった場合、AppModel クラスとして生成されるということです。

usesプロパティに存在しないモデルを指定('User'と指定しないといけないのに'Users'にしてたとか)して、バリデーションがうまく動かずに困ったことがある人は結構いると思うんですが、それはここで AppModel が生成されるからになります。

ということで Controllerでモデルを使用する場合の注意点をまとめると...

  • uses プロパティには必要最低限のモデルを指定する
  • 追加でモデルをロードするには loadModel を使う
  • モデルを使用しない場合は null か array()
  • uses プロパティに存在しないモデルを指定すると AppModel になる

Modelのロードはそれなりに重たい処理なので、不必要なモデルは極力ロードしないように気をつけましょう!

ということで、明日の担当は connvoi_tyou さんです。よろしくお願いします!