VOYAGE GROUP エンジニアブログ

voyagegroup_techのブログ
VOYAGE GROUPエンジニアブログです。

PHP

Phalcon Punch!!!

こんにちは。VOYAGE MARKETINGで学生インターンをしている西尾@blackstar240と申します。

突然ですが、弊社にはCREEDという経営理念があり、その中の一つに
『圧倒的スピード。』
という言葉があります。
本日は『圧倒的スピード。』を誇るPHPのフレームワーク、Phalconを使い、テストプロダクトを作ったことについて書こうと思います。

はじめに


はじめに、Phalconについて簡単にご紹介します。
Phalconとは、C言語で実装されたPHP Extentionであり、
こちらのベンチマーク結果からもお分かりのように、PHPのフレームワークの中では『圧倒的スピード。』を誇るフレームワークです。
BenchExample
また、devtoolsという、スケルトンコードを生成する便利なスクリプトのコレクションもあり、
これまた『圧倒的スピード。』で実装が出来そうな予感がします。
早速、こちらを参考にフレームワークとdevtoolsのインストールを行い、
さくっとプロダクトを作ってみようと思います。

雛形作り


まず、devtoolsを使ってMVCモデルの雛形を作ります。
Webサーバーのドキュメントルートで
$ phalcon project [project name]
コマンドを叩いて下さい。
そうすると、プロジェクトの雛形が完成します。
ProjectHinhagata
続いて、controllerの雛形を作ります。
[project name]ディレクトリ直下で
$ phalcon controller [controller name]
コマンドを叩いてください。
すると、Phalconの命名規則にのっとった名前に変換され、controllerの雛形も完成されます。
ControllerHinagata
続いては、controllerにecho文を書き、正しく呼び出されているか確認してみようと思います。。。が、

routing


まだ、routingを書いていません!!
これでは、せっかく書いたcontrollerも動くはずがありません。
ここは落ち着いてroutingを記述しましょう。
まず、configディレクトリ配下にroutes.phpファイルを作成します。
config/route.phpの記述例がこちらになります。

add("/phalcon", array(
    'controller' => 'phalcon',
    'action' => 'phalcon',
));

$router->add("/punch", array(
    'controller' => 'phalcon',
    'action' => 'punch',
));

return $router;

続いて、confifg/service.phpに以下の記述を追記します。

/**
 * add routing capabilities
 */
$di->set('router', function(){
    require __DIR__.'/routes.php';
    return $router;
});

$diコンテナにsetすることで依存関係をすっきりさせることが出来ますね!!

これで、routingは完成しましたが、今のままだと、
Built-in serverではhttp://localhost:9000/index.php?_url=$1のリクエストで開発しつづけなければなりません
そこで、先ほど作ったconfig/routes.phpに以下の記述を追記しましょう。

$router->setUriSource($router::URI_SOURCE_GET_URL);
$router->setUriSource($router::URI_SOURCE_SERVER_REQUEST_URI);

これで、http://localhost:9000/phalconのような
綺麗なURIでの実装も可能となりました。

テンプレートの使い分け


ここまで、controllerから直接echo文を実行し、挙動を確認してきました。
続いて、viewのテンプレートを各コンテキストごとに使い分けてみようと思います。
まず、app/views/layoutディレクトリにcontrollerと対応する名前の.volt(.phtml)ファイルを作成します。
ViewsHinagata
controllerからメソッドでviewファイルへのレンダリングを記述します。

view->setTemplateAfter('phalcon');
    }

    public function punchAction()
    {
        $this->view->setTemplateAfter('punch');
    }

}

ここまで記述した所で、実際の挙動を見てみましょう。

Phalcon

Punch

Finish

見事、ファルコンパンチが繰り出されました!!

感想


今回、Phalconを使ってテストプロダクトを作成致しました。日本語でPhalconについて紹介する記事がまだまだ少ない中、開発において必要不可欠な要素についてご紹介することが出来たので、Phalconを使ってみたいと思っている方の一助となれば幸いです。
Webサービス作りにおいて、フレームワークの選択が重要となる昨今、今回のテストプロダクト作りで得た知見も活かし、今後も努力を重ねていく所存であります。
また、公式ドキュメント上にはサンプルコードも掲載されているので、よろしければお試し下さい。
最後に、このエントリーの内容を実装したものがこちらになります。
https://github.com/Nissy0409/phalcon

最後までお付き合いいただき、ありがとうございました。

Apple信者ならFlash使わずPHP拡張face_detectで顔認証するよね !

こんにちは、VOYAGE GROUPのエンジニア、ガイアです。今は、ECナビのスマホサイトの開発運用をしています。

僕はECナビのスマホサイトを8ヶ月利用して5万ポイント貯めました。

貯めたポイントをWebマネーに変えて、音楽でも買おうと思います。まあ、ステマはこのぐらいにして本題に入ります。(5万ポイントは本当です、信じてください)

現在、Webで配信されるコンテンツはテキストに始まり、画像、音声、映像ときて、今はインタラクションのあるコンテンツもごく当たり前に配信されてます。javascript、HTML5、Unityなど色々と技術はありますが、やはりWebとの親和性や、普及度などなど・・・結局、色々物議を醸し出していますが、Flashで作られたコンテンツが多いのが現状です。ただ、Apple信者としてはiPhoneやiPadに対応したコンテンツにしたいところ、Flashを使ったコンテンツは少しばかり抵抗があります。Apple曰く「アプリでやればいいじゃない」というツンデレっぷりです。

そんな事を考えている時、Webで顔認識をやりたいという願いが降り落ちて来ました。最善はFlashだろうと思ったのですが、このご時世iPhoneは外せない。という訳で他の方法を模索するに至りました。顔認識についてはOpenCVというオープンソースのコンピュータビジョン用のライブラリを利用するのが一番楽だと信じているので、それをWebのインターフェイスから利用しようと妄想を走らせ、Google先生にお伺いを立ててみると、PHPからOpenCVを使う方法があるみたいです。Sounds great!
PHPのExtensionにface_detectという拡張機能があり、それを使います。

さあ、前置きはこのぐらいにして実際の作業に入りましょう。
詳しくはXarg.orgに情報があります。

環境設定 
Scientific Liunux 5を利用しています。OSはなんでもいいでしょう。

インストールするもの
  • httpd
  • php5.3
  • php-devel
  • php-gd
  • OpenCV2.3
  • php face_detect extension 

php-gdあたりまでは楽に揃えられると思います。パッケージ管理ツールで揃えてしまいましょう。php-gdをインストールしたら、phpinfo のページを作って GD が有効になっていることを確認します。

gd


画像表示
次に、PHPで画像を表示させてみましょう。phpanualからPHPの画像表示のコードを拝借します。
imagecreatefromjpeg :新しい画像をファイルあるいは URL から作成する


lena

OpenCVのインストール
画像は表示されましたか?では、次にOpenCVをインストールします。OpenCVは2.3が推奨です。
OpenCVはリポジトリに無いことが多いので、ここを参考にさせて頂きました。
mk-mode BLOG * Scientific Linux - OpenCV をソースからインストール
ソースからOpenCVをインストールするときにcmakeを利用するのですが、リポジトリからcmakeをインストールすると2.6系が入り、このページの通りに進めていくとエラーが出てしまいます。ソースパッケージからcmakeの2.8系をインストールすれば解決します。その他、gc++が必要だったりしますが、エラーが出たら、適宜インストールして下さい。


facedetect extension
OpenCVをインストールしたら、facedetect extensionをインストールします。
Xarg.orgにインストール方法が書いてあります。


 Install OpenCV (OpenCV 2.3.1)
 Download facedetect source package
 Unpack facedetect source package
 Go to facedetect folder and type "phpize && ./configure && make && make install"
 Make sure you have extension=facedetect.so in your php.ini


コマンドだとこんな感じです。簡単ですね。(権限で怒られたら、適宜権限を追加するなり、コマンドを一つづつ実行するなりして下さい。)
  • git clone https://github.com/infusion/PHP-Facedetect.git
  • cd PHP-Facedetect
  • phpize && ./configure && make && make install
インストールが終わったらphp.iniに extension=facedetect.so を追記して、facedetectを有効化します。その後 phpinfo のページでfacedetectが有効化されていることを確認します。これで準備は万端です。
facedetect

因みに、facedetect extensionをインストールすると2つの関数が使えるようになります。
  • face_count('party.jpeg', 'cascade.xml') 顔の数を返す
  • face_detect('party.jpeg', 'cascade.xml') 顔の場所の配列を返す
第一引数は、画像ファイル、第2引数はOpenCVでオブジェクト検出に利用される分類器です。この分類器に関してはOpenCVに学習済みのサンプルがあります。OpenCVインストール時に解凍したディレクトリ OpenCV-2.3.0/data/haarcascades/ 以下にあるxmlがそのデータです。

ついに顔認識!!
さあ、環境設定も終わり、あとはコードを書くだけです、先ほどの画像表示のコードを変更します。
lena_face

よく見る出力結果になりましたね。PHPで顔認識をすることができました。みなさんも、PHPで顔認識を楽しんで下さい。

face_detect_murata


・・・

「いやいやいや、ちょっとまって、なんだよ、PHPで顔認識って、その処理、全部サーバでやる気かよ、そこはFlashだろjk」
っておみさんに言われそうな仕様です。
 
今回VirtualBoxを使っていたのですが、実行速度も・・・
これでは、ユーザの同時アクセスに耐えれそうにありません・・・
PHPで顔認識ってニーズあるんですかね。実現可能性が低いんでは・・・
そもそもOpenCVの顔認識って色々オプションあったよね、そんなのも設定できないんじゃ・・・


「まだだ、まだ終わらんよ」

こうなったら更にニッチなところへと足を踏み入れていく次第です。

次回
「サンプルコードでDeveloper!? OpenCVで学ぶ!自作 PHP Extension」




Behatでケータイサイトの受け入れテスト

はじめまして、株式会社Flesselの田中と申します。

私は長いことケータイサイトを作る仕事に関わってきました。
縮小傾向にあるフィーチャーフォンですが、まだまだ現役です。

このエントリーではPHPのストーリーテストツールBehatを利用して、
ケータイサイトの受け入れテストを行う方法をご紹介します。

インストール
今回は対象となるプロジェクトにcomposerを使ってBehatを組み込む方法をとります。

まずはcomposerをインストールします。
curl -s https://getcomposer.org/installer | php
※CentOS環境だと証明書の関係で動かないことがあります。

次にcomposerの設定ファイルであるcomposer.jsonをプロジェクト直下に作成します。
今回はBehatともにMinkというブラウザテストの抽象化ライブラリを使うので、これも一緒に設定します。
{
    "require": {
        "behat/behat": ">=2.4@stable",
        "behat/mink":  "1.4@stable",
        "behat/mink-extension": "*",
        "behat/mink-goutte-driver": "*"
    },

    "config": {
        "bin-dir": "bin/"
    }
}
composer.jsonが用意できたら、インストールコマンドを叩いて依存するライブラリをインストールします。 
php composer.phar install
これでvendorディレクトリの中にbehatがインストールされ、binディレクトリにbehatコマンドができます。
(※2012年8月3日現在、依存関係が解決できずにインストールが失敗するようです)

プロジェクトの初期化
behatがインストールされたのでbehatが利用するファイルを初期化します。
bin/behat --init
これでプロジェクト直下に下記のファイルが作成されます。
features/bootstrap/FeatureContext.php
このファイルにテストコードを記述することになります。

フィーチャー定義を用意する
フィーチャーとはアプリケーションが持つ個別の機能のことです。Behatでは各フィーチャーごとにテストシナリオが書かれたファイルを用意します。
このファイルは拡張子をfeatureとしてfeaturesディレクトリに配置します。

各ファイルは自然言語に近い記述で書きます。
今回は次の定義をsearch.featureとして作成しました。
# language: ja 
フィーチャ: 検索機能
  欲しい商品を見つけるために
  ユーザーとして
  商品を検索できる

  背景:
    前提 au端末で接続する

  シナリオ: カメラを検索する
    かつ"/" を表示している
    もし"keyword" フィールドに "camera" と入力する
    かつ"検索" ボタンをクリックする
    ならば"「camera」の検索結果" と表示されていること
    かつ"「camera」ランキング 1位" と表示されていること

  シナリオ: ヒットしない単語で検索する
    かつ"/" を表示している
    もし"keyword" フィールドに "fak;efalkjekd" と入力する
    かつ"検索" ボタンをクリックする
    ならば"ご指定の検索条件に該当する商品はありませんでした。" と表示されていること
日本語で書かれていてとてもわかりやすいと思います。
各シナリオの「前提」からはじまる行以降はステップと呼ばれ、テストはこのステップごとに実行されていきます。
ステップ中のダブルウォーテーションで囲われた文字列が変数として扱われます。

さて、ここで一度テストを実行してみます。
step01
黄色くなっているところがテストが未実装なステップです。また、下の方にテストを実装する際のスニペットも表示されています。
通常はこのスニペットをコピペしてテストを実装していく流れになります。


MinkContextを利用する
単純なブラウザをつかったテストであれば、今回一緒にインストールしたMinkExtensionが提供するMinkContextを用いると自分でステップを実装せずにテストすることができます。
MinkContextが提供しているステップについてはbehat -diコマンドで参照できます。日本語のステップについては https://github.com/Behat/MinkExtension/blob/master/i18n/ja.xliffで確認できます。

便利なMinkContextを利用するにはFeatureContext.phpに次の修正を加えます。
--- features/bootstrap/FeatureContext.php.orig  2012-08-02 08:01:36.000000000 +0900
+++ features/bootstrap/FeatureContext.php       2012-08-02 08:03:03.000000000 +0900
@@ -7,6 +7,8 @@
 use Behat\Gherkin\Node\PyStringNode,
     Behat\Gherkin\Node\TableNode;
 
+use Behat\MinkExtension\Context\MinkContext;
+
 //
 // Require 3rd-party libraries here:
 //
@@ -17,7 +19,7 @@
 /**
  * Features context.
  */
-class FeatureContext extends BehatContext
+class FeatureContext extends MinkContext
 {
     /**
      * Initializes context.

また、次の内容のbehat.ymlをプロジェクトルートに作成します。
# behat.yml
default:
  extensions:
    Behat\MinkExtension\Extension:
      base_url: 'http://example.com/'
      goutte:    ~

base_urlにはテスト時にアクセスするサーバーのベースURLを設定します。

ここでテストを実行すると次のようになります。
step02
「au端末で接続する」というステップ以外は青になりテスト実装が加わったことがわかります。

独自のステップを実装する
「au端末で接続する」はケータイサイト特有のステップですから当然提供されていません。
今回はau端末での接続をau端末のUser-AgentとEz番号をHTTPヘッダにもつという条件として定義します。

これのステップの実装は次のようになります。
    /**
     * @Given /^au端末で接続する$/
     */
    public function au端末で接続する()
    {
        $this->getSession()
        ->getDriver()
        ->getClient()
        ->setServerParameters(['HTTP_USER_AGENT' => 'KDDI-CA39 UP.Browser/6.2.0.13.1.5 (GUI) MMP/2.0']);
        $this->getSession()->setRequestHeader('x-up-subno', '10msimmsim000_vr.ezweb.ne.jp');
    }
MinkContextを利用している場合にヘッダを設定するにはx-up-subnoを設定しているように$this->getSession()->setRequestHeader()を用いればよいのですが、
今回ブラウザの実装として利用しているGoutteがsetRequestHeaderを通したユーザーエージェントの書き変えに対応していないためこのような形になっています。

実行する
それではすべてのステップの実装ができたのでbehatコマンドを叩いてテストを実行してみます。
step03
すべてのステップがグリーンになりました! 簡単ですね!

まとめ
Behatでは自然言語に近いフィーチャー定義を利用するので、エンジニア以外でもテストの概要を把握することができます。
しかも、MinkExtensionと組み合わせることで容易にブラウザテストをできるのは大変魅力的です。
皆さんもぜひ使ってみてください。

闇PHP Matsuri2011とニンジャの隠された真実

PHP Matsuri2011というハッカソンイベントで、闇PHP Matsuriというセッションが深夜に行われました。
DSC05702
koyhoge All Rights Reserved


実はこのセッションは、VOYAGE GROUPの手の者たちが企画・開催を行なっていました。な、なんだってー!(AA略)

闇PHP Matsuri2011とは

インスパイア元は、闇RubyKaigi2011です。闇というと闇プログラマネタを想起する方も多いかもしれませんが、そちらの意図ではありません。
闇RubyKaigi2011では、下記の狙いで開催されたとRubyistMagazineの記事の中で書かれていますが、この闇PHPMatsuriでも同様の狙いであり、もっとトーカーが増えてくれたらいいなあと思い、開催しました。
LightningTalks との差別化を考えました。当初は話慣れてなくても気軽に話せるのが LightningTalks の持ち味でしたが、最近はいきなり挑戦するにはハードルが高くなっているのではと感じています。そこで LightnigTalks よりもっと気負わずに話ができるようにしたいと考えました。 そこで、5 分より短い時間持ち時間で、当日応募を受け付けるという RejectTalks に似たような形式にしました。 ただ当日応募は場の熱気と勢いといったついカッとなるための要素が応募の敷居に作用してくるため、本当に応募が集まるか不安がありました。よって事前応募も行うこととしました。

得られた実装

  • 1人あたり持ち時間5分の一般的なライトニングトークス
  • 5分経ったら、ニンジャペアがドラを叩いてトークを打ち切った
  • 同時にもう一つのニンジャペアが5分立ったらニンジャソードで斬りかかった
  • 大多数のトーカーが斬られリアクションを取ってくれた

結果どうだったか

正直、受け入れてもらえるかとても心配でご飯が喉を通らない程だったのですが、けっこう楽しんでいただけたようで、ホッとしました。
また機会があれば、今回の弊社の手の者たちもどこかでやらかすかと思いますし、是非多くの方々に闇イベントを開いてもらえればいいなあと思っています。

これからの闇

京都で、2011年11月に関西闇Ruby会議というイベントが行われるらしいです。 ご興味の有る方は参加してみると、できれば発表してみると、とても楽しいかと思います。 わたしも行きたかった…

参考リンク

全ては網羅できてませんが、ブログ類のリンク集、Twitterまとめ、写真へのリンクを貼っておきますね。

感想ブログ、写真(by 公式サイト)
http://2011.phpmatsuri.net/page/blog-and-picture-of-participants

Twitterまとめ(2011/10/15 22:30ごろからが闇PHPMatsuriタイムです)(by Togetter)
http://togetter.com/li/201224

ニンジャ写真(by koyhoge)
http://www.flickr.com/photos/koyhoge/6246567037/in/set-72157627775049941
http://www.flickr.com/photos/koyhoge/6246567037/in/set-72157627775049941
http://www.flickr.com/photos/koyhoge/6247088480/in/set-72157627775049941
http://www.flickr.com/photos/koyhoge/6247087478/in/set-72157627775049941
http://www.flickr.com/photos/koyhoge/6247089444/in/set-72157627775049941
http://www.flickr.com/photos/koyhoge/6246569675/in/set-72157627775049941

第2回 CakePHP2.0 勉強会@Tokyo で会場を提供させていただきました

こんにちは!株式会社adingoのエンジニアで前田(@brtriver)といいます。


写真(2)

2011年10月06日に、第2回 CakePHP2.0 勉強会@Tokyo が開催され、VOYAGE GROUPで勉強会/懇親会会場を提供させていただきました。
また、当日は VOYAGE BB ポイントが溜まるWiMAXこと VOYAGE WiMAX を用意し回線を提供しつつ、Ustreamで勉強会の様子を配信しましたが、最終的に100人以上の視聴者になりました。

キャンセル待ちが出るほど盛況なことからも分かるように、CakePHPは代表的なPHPフレームワークの1つで国内でも多くの利用実績がある点や、もうすぐ正式版がリリースされるCakePHP2の勉強会ということもあり、今回の勉強会もかなり注目度は高かったと思います。

スタッフの皆様、ご参加いただいた皆様ありがとうございました!

全てではありませんが、資料をアップされていた方のリンク先は以下にまとめました(漏れがありましたらご指摘ください)

懇親会の様子はUstreamで配信していませんでしたが、懇親会はAjitoにて開催し、懇親会LTも大盛り上がりでした。

写真(3)


懇親会で個人的に印象的な内容だったのはCandyCaneでした。
CandyCaneはPHP版Redmineであり、CakePHPで開発されています。
最近になり、CakePHPのコアデベロッパーが開発に参加するなど世界的にブレークの兆しがあります。
特徴は、とにかく導入の敷居がRedmineと比べても低い!インストールを動画で紹介していましたがなんと2分掛かっていません。
おそらくCakePHPのキラーアプリになるのではないでしょうか?


最後に、VOYAGE GROUPでは、このように勉強会の会場を無償で提供させていただいています。
もし勉強会を企画していて会場探しにお困りの場合は、私(@brtriver)やVOYAGE GROUPの誰かにご相談いただければと思います。

記事検索
QRコード
QRコード